VueX是专门为vue.js开发的状态管理模式,集中管理应用的所有组件的状态/数据,解决多组件的数据通信。当多个组件依赖于同一种状态/数据(e.g.使用数据),或者来自于不同组件的行为需要变更同一状态/数据时(e.g.修改同一数据),可以使用vuex。
1. VueX组成部分
VueX的核心属性中包含state、actions、mutations、getters和module五个部分,由store管理,其中:
- state:用来定义全局的数组、对象、字符串等数据,这些数据允许所有组件共享和修改。
- 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)
- actions:action中定义了需要处理state中数据的动作,组件通过dispatch函数可提交该动作以及该动作所涉及的参数信息,另一方面,当执行动作所涉及的参数组件未知,需要通过第三方获取,例如后端的API数据,则需要在action中进行异步任务的请求。在明确动作且获得必要参数数据后,通过调用commit函数将这些必要信息提交给mutation实际执行动作。简单来说,action处理的是动作执行前的准备工作,action无法直接修改state,需要借助mutation来实现。
- mutations:定义了处理state数据的实际执行操作,也是修改state数据的唯一方法。在mutations中执行的是同步操作。
- 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)