美文网首页
聊聊Vuex(一)

聊聊Vuex(一)

作者: moofyu | 来源:发表于2020-03-17 14:42 被阅读0次

    Vuex 是什么?

    • 状态管理库
    • 集中式存储管理应用的所有组件状态
    • 五个重要属性 stategettersmutationsactionsmodules

    总结

    • state:基本数据
    • getters:从基本数据派生的数据,可以对state进行计算操作
    • mutations:提交更改数据的方法,同步!
    • actions:像一个装饰器,包裹mutations, mutation,使之可以异步
    • modules: 模块化Vuex

    State

    • Vuex中的基本数据
    • Vuex使用单一状态树:用一个对象就包含了全部的状态数据。state定义了所有需要的基本状态参数

    获得Vuex的state方法

    • 我们可以通过Vue的Computed获得Vuex的state,如下:
    computed: {
            count: function(){
                return this.$store.state.count 
            }
     }
    
    • mapState辅助函数
    import { mapState } from 'vuex'
    export default {
      // ...
      computed: mapState({
        // 箭头函数可使代码更简练
        count: state => state.count,
        // 传字符串参数 'count' 等同于 `state => state.count`
        countAlias: 'count',
        // 为了能够使用 `this` 获取局部状态,必须使用常规函数
        countPlusLocalState (state) {
          return state.count + this.localCount
        }
      })
    }
    

    当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组

    computed: mapState([
      // 映射 this.count 为 store.state.count
      'count'
    ])
    

    展开运算符

    computed: {
      localComputed () //本地计算属性
      //使用对象展开运算符将此对象混入到外部对象中
      ...mapState({
        //..
      })
    }
    

    getters

    • 即从store的state中派生出的状态。
    • 可以对state进行计算操作,它就是store的计算属性
    const store = new Vuex.Store({
        state: {
            count:0
        },
        getters: {
            // 单个参数
            countDouble: function(state){
                return state.count * 2
            },
            // 两个参数
            countDoubleAndDouble: function(state, getters) {
                return getters.countDouble * 2
            }
        }
    })
    
    

    获取getter方法

    • 通过Vue的Computed获得Vuex的getters。
    computed: {
            count: function(){
                return this.$store.state.count
            }
            .......
    }
    
    • mapGetters 辅助函数
    import { mapGetters } from 'vuex'
    
    export default {
      // ...
      computed: {
      // 使用对象展开运算符将 getters 混入 computed 对象中
        ...mapGetters([
          'countDouble',
          'CountDoubleAndDouble',
          //..
        ])
      }
    }
    
    

    如果你想将一个 getter 属性另取一个名字,使用对象形式

    mapGetters({
      // 映射 this.double 为 store.getters.countDouble
      double: 'countDouble'
    })
    

    mutations

    • 提交更改数据的方法,同步!
    • mutation必须是同步的,如果要异步需要使用action。
    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        //无提交荷载
        increment(state) {
            state.count++
        }
        //提交荷载
        incrementN(state, obj) {
          state.count += obj.n
        }
      }
    })
    
    

    更新方法:调用 store.commit 方法

    //无提交荷载
    store.commit('increment')
    //提交荷载
    store.commit('incrementN', {
        n: 100
      })
    
    或者
    
    store.commit({
      type: 'incrementN',
      n: 10
    })
    

    在组件中更新store数据

    1. this.$store.commit(‘xxx’) 提交 mutation
    2. mapMutations 辅助函数
    import { mapMutations } from 'vuex'
    
    export default {
      //..
      methods: {
        ...mapMutations([
          'increment' // 映射 this.increment() 为 this.$store.commit('increment')
        ]),
        ...mapMutations({
          add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
        })
      }
    }
    
    

    actions

    • Action 提交的是 mutation,而不是直接变更状态。
    • Action 可以包含任意异步操作。
    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          setInterval(function(){
            context.commit('increment')
          }, 1000)
        }
      }
    })
    
    

    注意:Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

    • Action 通过 store.dispatch 方法触发
    store.dispatch('increment')
    
    • Actions 支持同样的载荷方式和对象方式进行分发
    // 以载荷形式分发
    store.dispatch('incrementN', {
      n: 10
    })
    
    // 以对象形式分发
    store.dispatch({
      type: 'incrementN',
      n: 10
    })
    
    • mapActions辅助函数
      你在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用
    import { mapActions } from 'vuex'
    
    export default {
      //..
      methods: {
        ...mapActions([
          'incrementN' //映射 this.incrementN() 为 this.$store.dispatch('incrementN')
        ]),
        ...mapActions({
          add: 'incrementN' //映射 this.add() 为 this.$store.dispatch('incrementN')
        })
      }
    }
    
    

    Modules

    • 模块化Vuex

    使用单一状态树,导致应用的所有状态集中到一个很大的对象。但是,当应用变得很大时,store 对象会变得臃肿不堪。
    为了解决以上问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters、甚至是嵌套子模块——从上至下进行类似的分割:

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
    

    模块的局部状态

    对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态,对于模块内部的 getter,根节点状态会作为第三个参数:

    const moduleA = {
      state: { count: 0 },
      mutations: {
        increment (state) {
          // state 模块的局部状态
          state.count++
        }
      },
    
      getters: {
        doubleCount (state) {
          return state.count * 2
        },
        sumWithRootCount (state, getters, rootState) {
          return state.count + rootState.count
        }
      }
    }
    
    

    同样,对于模块内部的 action,context.state 是局部状态,根节点的状态是 context.rootState:

    const moduleA = {
      // ...
      actions: {
        incrementIfOddOnRootSum (context) {
          if ((context.state.count + context.rootState.count) % 2 === 1) {
            commit('increment')
          }
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:聊聊Vuex(一)

          本文链接:https://www.haomeiwen.com/subject/ryktyhtx.html