Vue状态管理

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue状态管理相关的知识,希望对你有一定的参考价值。

1.什么是状态管理?

由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长,所以 Vuex是Vue团队提供的一套组件状态管理维护的解决方案

  • 作用

    • 进一步完善了Vue基础代码功能
    • 使Vue组件状态更加容易维护
    • 为大型项目开发提供了强大的技术支持
  • 使用

    <script src="vue.js"></script>
    <script src="vuex.js"></script>
    
    <div id="app">
      <p>{{this.$store.state.name}}</p>
    </div>
    
    var store = new Vuex.Store({
      state: {
        name: '我是vuex'
      }
    })
    
    var vm = new Vue({
      el: '#app',
      store
    })
    
  • 核心

    每一个Vuex应用的核心就是store(仓库),即响应式容器,它用来定义应用中数据以及数据处理工具

    • Vuex的状态存储是响应式的,当store中数据状态发生变化,那么页面中的store数据也发生相应变化
    • 改变store中的状态的唯一途径就是显式地提交mutation,这样可以方便地跟踪每一个状态的变化
  • 配置选项

    var store = new Vuex.Store({
        state:{},
        mutations:{},
        actions:{},
        modules:{},
        plugins:{},
        getters:{},
        devtools:true
    })
    

2.下载使用

  • 计算属性使用store

    <script src="vue.js"></script>
    <script src="https://unpkg.com/vuex@3.5.1/dist/vuex.js"></script>
    
    <div id="app">
      <p>{{name}}</p>
    </div>
    
    var store = new Vuex.Store({
      state: {
        name: '我是vuex'
      }
    })
    
    var vm = new Vue({
      el: '#app',
      store,
      computed: {
        name () {
          return this.$store.state.name
        }
      }
    })
    
    
  • mapState使用store

    <script src="vue.js"></script>
    <script src="https://unpkg.com/vuex@3.5.1/dist/vuex.js"></script>
    
    <div id="app">
      <p>{{name}}</p> : <p>{{age}}</p>
    </div>
    
    var store = new Vuex.Store({
        state: {
            name: '我是vuex',
    		age: 20
        }
    })
    
    var mapState = Vuex.mapState
    
    var vm = new Vue({
        el: '#app',
        store,
        computed: mapState({
            name: state => state.name,
            age: state => state.age
        })
    })
    

3.管理模式

在Vue中,组件的状态变化是通过Vue单向数据流的设计理念实现的

  • 单项数据流机制

    • State:驱动应用的数据源
    • View:以声明方式将state映射到视图
    • Actions:响应在View上的用户输入导致的状态变化

  • 单项数据流示例

    new Vue({
        // State
        data () {
            return { count: 0 }
        },
        // View
        template: '<div>{{ count }}</div>',
        // Actions
        methods: {
            increment () {
                this.count++
            }
        }
    })
    
  • Vuex出现缘由

    • 单项数据流机制增强了组件之间的独立性,但是当有多个组件共享某一个状态值时,这种数据流状态就会被破坏
    • 为了数据维护更加方便,所以需要将共享状态抽离出来
    • 而Vuex就是专门为Vue设计的状态管理库,以利用Vue的细粒度数据响应机制来进行高效的状态更新
  • Vuex工作流程

    • Actions中定义事件的回调方法,通过Dispatch触发事件,是异步执行的,专注于业务逻辑
    • Mutations通过Commit提交,是同步执行的,专注于修改State中的全局状态数据

4.配置选项

  • actions

    actions选项用于定义事件处理方法,用于处理state中的数据,类似于mutations,不同之处在于actions是异步执行的。事件处理函数可以接收commit对象,完成mutations提交。

    • 参数传递

      <div id="app">
          <button @click="see_mutations">查看mutations接收的参数</button>
          <button @click="see_actions">查看actions接收的参数</button>
      </div>
      
      var store = new Vuex.Store({
          state: {
              name: 'lisi',
          },
          mutations:{
              test(state){
                  console.log(state)
              }
          },
          actions:{
              test1(context){
                  console.log(context)
              },
              test2(context, param){
                  console.log(param)
              },
              test3(context, param){
                  console.log(param)
              }
          }
      })
      
      var vm = new Vue({
          el: '#app',
          store,
          methods:{
              see_mutations(){
                  this.$store.commit('test')
              },
              see_actions(){
                  this.$store.dispatch('test1')
                  this.$store.dispatch('test2','传入的值')
                  this.$store.dispatch({"type":'test3',"content":'传入的值'})
              }
          }
      })
      
    • 案例演示

      <div id="app">
          <button @click="add">计数器</button>
          <span v-text="count"></span>
      </div>
      
      var store = new Vuex.Store({
          state: {
              count: 0,
          },
          mutations:{
              change(state){
                  state.count++
              }
          },
          actions:{
              add(context){
                  context.commit('change')
              }
          }
      })
      
      var vm = new Vue({
          el: '#app',
          store,
          computed:{
              count(){
                  return this.$store.state.count
              }
          },
          methods:{
              add(){
                  this.$store.dispatch('add')
              }
          }
      })
      
  • mutations

    mutations中的方法主要用来对state进行数据操作,在组件中完成mutations提交就可以完成组件状态更新

    • 参数传递

      <div id="app">
          <button @click="send">发送参数</button>
          <span v-text="show"></span>
      </div>
      
      var store = new Vuex.Store({
          state: {
              msg: '',
          },
          mutations:{
              receive(state, param){
                  state.msg = param
              }
          }
      })
      
      var vm = new Vue({
          el: '#app',
          store,
          computed:{
              show(){
                  return this.$store.state.msg
              }
          },
          methods:{
              send(){
                  this.$store.commit('receive','hello world')
                  this.$store.commit({"type":'receive',"message":'hello world'})
              }
          }
      })
      
    • 同步回调

      • 在调试组件状态时,mutations提交的日志信息都会被记录下来
      • 触发mutations中的事件处理方法来更新页面状态的变化,这就是一种同步状态
      • mutations本身的同步方法是同步执行,这样就可以记录当前状态的变化,同步到页面中
    • 异步回调

      • 对于mutations事件处理方法中的诸如setTimeout这样的回调函数,那么当执行时任何回调函数中进行的状态改变都是不可追踪的
      <div id="app">
          <button @click="add">异步回调执行</button>
          <span v-text="count"></span>
      </div>
      
      var store = new Vuex.Store({
          state: {
              count: 0
          },
          mutations:{
              receive(state){
                  console.log(state)
                  setTimeout(function(){
                      state.count++
                  },1000)
              }
          }
      })
      
      var vm = new Vue({
          el: '#app',
          store,
          computed:{
              count(){
                  return this.$store.state.count
              }
          },
          methods:{
              add(){
                  this.$store.commit('receive')
              }
          }
      })
      
  • getters

    store实例允许在store中定义getters计算属性,类似于Vue实例的computed

    <div id="app">
        <input @keyup.enter="search" v-model="name" placeholder="请输入商品名"/>
        <div v-text="good"></div>
        <ul v-for="good in goods" :key="good.name">
            <li>
                <span v-text="good.name"></span>-<span v-text="good.price"></span>
            </li>
        </ul>
    </div>
    
    var store = new Vuex.Store({
        state: {
            goods: [
                {"name":'商品1',"price":2000},
                {"name":'商品2',"price":500},
                {"name":'商品3',"price":1200}
            ],
            name: ''
        },
        mutations:{
            change(state,name){
                state.name = name
            }
        },
        getters:{
            good: state => {
                return state.goods.filter(good => good.name === state.name)
            }
        }
    })
    
    var vm = new Vue({
        el: '#app',
        data:{
            name: ''
        },
        computed:{
            goods(){
                return this.$store.state.goods
            },
            good(){
                return this.$store.getters.good
            }
        },
        methods:{
            search(){
                this.$store.commit('change',this.name)
            }
        },
        store
    })
    
  • modules

    modules用来在store实例中定义模块对象,在开发中页面组件存在多种状态,且都是通过单一状态树形式实现数据状态可跟踪的,Vue为了解决这种问题,提出了类似于模块化开发的方式对store对象仓库进行标准化管理。

    const module1 = {
        state:{
            name: '模块1'
        }
    }
    const module2 = {
        state:{
            name: '模块2'
        }
    }
    var store = new Vuex.Store({
        modules:{
            m1:module1,
            m2:module2
        }
    })
    
    var vm = new Vue({
        el: '#app',
        store
    })
    
    console.log(vm.$store.state.m1)
    console.log(vm.$store.state.m2)
    
  • plugins

    Vuex中的插件配置选项为plugins,插件本身为函数,函数接收参数store

    const myPlugin = store => {
        // 当store初始化后调用
        store.subscribe((mutation,state) => {
            // 每次mutation提交后调用,mutation格式为 {type, payload}
            console.log(mutation.type, mutation.payload)
        })
    }
    
    var store = new Vuex.Store({
        mutations:{
            show(state){
                console.log(state)
            }
        },
        plugins:[myPlugin]
    })
    
    store.commit('show','message')
    
  • devtools

    **devtools选项用来设置是否在devtools调试工具中启用Vuex,devtools选项经常用在一个页面中存在多个store实例的情况 **

    var store = new Vuex.Store({
        devtools:true
    })
    

5.状态管理中的API

  • 模块注册

    store实例对象提供了动态创建模块的接口,也就是store.registerModule()方法,同时还可以使用store.unregisterModule()方法来卸载Module

    var store = new Vuex.Store({})
    
    store.registerModule('myModule',{
        state:{
            name: '我是动态注册的Module'
        }
    })
    
    var vm = new Vue({
        el: '#app',
        store
    })
    
    console.log(vm.$store.state.myModule.name)
    
  • 状态替换

    用于对state数据状态进行操作,可以通过store.replaceState()方法实现状态替换,该方法接收新的state对象用来在组件中展示新对象的状态。

    var store = new Vuex.Store({
        state:{
            message: '修改前'
        }
    })
    var vm = new Vue({
        el: '#app'VSCode自定义代码片段13——Vue的状态大管家

    手把手教你学vue-4(vuex)

    Vue状态管理

    Vue状态管理

    VSCode自定义代码片段1——vue主模板

    VSCode自定义代码片段——.vue文件的模板