VueX学习

104 阅读2分钟

VueX是专门为vue.js开发的状态管理模式,集中管理应用的所有组件的状态/数据,解决多组件的数据通信。当多个组件依赖于同一种状态/数据(e.g.使用数据),或者来自于不同组件的行为需要变更同一状态/数据时(e.g.修改同一数据),可以使用vuex。

lifeCycle.png

1. VueX组成部分

VueX的核心属性中包含state、actions、mutations、getters和module五个部分,由store管理,其中:

  1. state:用来定义全局的数组、对象、字符串等数据,这些数据允许所有组件共享和修改。
  2. getters:对存储在state中的数据进行加工,此方式可被多处复用,getters中的函数默认传入4个参数,getters(本地state, 本地getters, 全局state, 全局getters)
// getters(localState,localgetters,globalState,globalGetters)
const getters = {
    bigSum(state){
        return state.sum * 10;
    }
}
console.log($store.getters.bigSum)
  1. actions:action中定义了需要处理state中数据的动作,组件通过dispatch函数可提交该动作以及该动作所涉及的参数信息,另一方面,当执行动作所涉及的参数组件未知,需要通过第三方获取,例如后端的API数据,则需要在action中进行异步任务的请求。在明确动作且获得必要参数数据后,通过调用commit函数将这些必要信息提交给mutation实际执行动作。简单来说,action处理的是动作执行前的准备工作,action无法直接修改state,需要借助mutation来实现。
  2. mutations:定义了处理state数据的实际执行操作,也是修改state数据的唯一方法。在mutations中执行的是同步操作。
  3. modules:当组件功能较复杂,可通过modules将数据模块化,每个模块中有独立的state、actions、mutations和getters。

mapState、mapGetters、mapActions以及mapMutations:

相较于传统的写法,通常会利用辅助函数mapState和mapGetters对仓库中的数据进行处理生成计算属性,利用mapAction与mapMutation直接提交对state的执行动作,而不是通过dispatch和commit来实现,这极大的简化了代码的编写。

· mapState:借助mapState生成计算属性,开发人员只需要以{key: value}的方式将计算属性名和属性名传给mapState处理即可:

import {mapState} from 'vuex'
computed:  {
    // 原始写法
    he() {
        return this.$store.state.sum
    }
    // mapState工具写法
    ...mapState({he: 'sum'}),    // 写法二: ...mapState(['sum']), 
}

...mapState({he: 'sum'}), 写法:通过mapState返回计算属性,相似的还有:...mapGetters()

· mapMutations:借助mapMutations生成对应的方法,方法中会调用commit去联系mutations,此方法需要注意在点击事件中需要手动添加要传的实参,如下:

// (对象写法)
<button @click="add(n)">+</button>
<button @click="substract(n)">-</button>
methods: {
  ...mapMutations({add: 'ADD', substract: 'SUB'});
}

// (数组写法)
<button @click="ADD(n)">+</button>
<button @click="SUB(n)">-</button>
// 将生产ADD(){this.$store.commit('ADD', this.n)}
methods: {
  ...mapMutations(['ADD', 'SUB']);
}

· mapActions:用于帮助生成actions对话的方法,即包括$store.dispatch(xxx)

// (对象写法)
<button @click="judgeSum(n)">add when odd</button>
<button @click="addDelay(n)">add after wait 1s</button>
methods: {
  ...mapActions({judgeSum: 'addOdd', addDelay: 'addWait'});
}

// (数组写法)
<button @click="addOdd(n)">add when odd</button>
<button @click="addWait(n)">add after wait 1s</button>
methods: {
  ...mapActions(['addOdd', 'addWait']);
}

2. VueX模块化思想

当包含多个组件模块,需要对不同的组件模块进行分类以便于代码的维护,此时需要对上述的人员列表模块和组件模块进行分离,各种写法如下:

// 模块化管理Vuex结构
const personOptions = {
    mutations: {},
    actions: {},
    state: {},
    getters: {}
}
const countOptions = {
    mutations: {},
    actions: {},
    state: {},
    getters: {}
}
export default new Vuex.Store({
  modules: {
    person: personOptions,
    count: countOptions
  }
});
// 数据引用(简写模式)
...mapState('count', ['sum']),
...mapState('person', ['personList']),
...mapMutation & ...mapGetters & ...mapActions写法同上

// 数据引用(原始写法)
// 引入person/以便Vue.store识别ADDPERSON对象属性
this.$store.commit('person/ADDPERSON', personObj);
this.$store.state.count.sum
this.$store.getters['person/firstPersonName']
this.$store.dispatch('person/addPersonWang', personObj)