Vuex
// 模块化开发
// 可以先声明多个子store,然后再传入Vuex.Store的构造函数:
const store1 = {
namespaced: true,// 开启命名空间
// 类似子组件的data,这里state必须是一个方法
state() {
return {}
},
getters: {},
mutations: {},
actions: {}
},
const store2 = {
namespaced: true,
state() {
return {
}
},
getters: {},
mutations: {},
actions: {}
}
...
const store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {
store1,
store2,
...
},
plugins: []
});
state
将store注入vue根实例,就可在每个子组件中通过this.$store
访问store。
new Vue({
el: '#app',
data: {},
store
})
store实例存放了一些所有子组件的公共数据和方法。
getters
getters包含一些方法,这些方法接收state作为第一个参数,并对state的属性进行特定计算后返回新的计算属性。
mutations
mutations是唯一更改state的方式。
mutations包含变更state的一些方法,一个方法名就相当于一个事件类型(type),这些方法也接收state作为第一个参数。
mutations中的方法不能直接调用,只能通过store实例的commit方法:
store.commit('type'); // type就是mutation的方法名
mutations的方法一般还接收第二个参数payload(一般是一个对象):
mutations: {
typeName (state, payload) {
}
}
此时,提交mutation时:
store.commit('typeName', { ... });// 传入的对象会传给payload
对象风格的提交方式:
store.commit({
type: 'typeName',
key: value,
...
})
此时的mutation方法依然不用改变,因为传入commit的对象会传给payload。
mutation必须是同步函数。
actions
actions中包含一些方法,这些方法用于提交mutation,方法接收与store实例有相同属性和方法的context对象:
actions: {
actionName (context, payload) {
context.commit('mutationType');
}
}
也可以解构context对象以简写:
actions: {
actionName ({commit}, payload) {
commit('mutationType');
}
}
actions中的方法通过store实例的分发来调用:
store.dispatch('actionName');
actions与mutations最大的不同就是actions中的方法可以是异步函数。
携带payload参数的分发:
store.dispatch('actionName', { ... });
等同于:
store.dispatch({
type: 'actionName',
key: value,
...
})
如果被分发的action方法返回一个Promise对象:
actions: {
actionName ({ commit }) {
return new Promise((resolve, reject) => {
commit('mutationName');
resolve();
})
}
}
则可以这样操作:
store.dispatch('actionName').then(() => ...)
在另外一个action中也可以这样:
actions: {
otherAction({ dispatch, commit }) {
return dispatch('actionName').then(() => {
commit('otherMutation');
})
}
}
辅助函数
store对象的四个配置选项各自都有一个辅助函数:
mapState
mapGetters
mapMutations
mapActions
首先从Vuex解构出这四个方法(需先引入Vuex):
let {mapState, mapGetters, mapMutations, mapActions} = Vuex;
或使用模块化开发时(需先安装vuex依赖):
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
然后在组件的computed和methods选项中使用:
computed: {
...mapState(store名, ['name1']);// 此时name1可以直接当计算属性使用了, 当有多个子store时,需指明store名
...mapGetters(['name2']);
// 若需重命名
...mapGetters(store名, {
newName: name
})
},
methods: {
...mapMutations(store名, ['methodName1']);// 此时methodName1可以当作组件方法使用了
...mapActions(store名, ['methodName2'];
}
在HTML中使用:
<div id="app">
属性的使用:{{ name1 }}
方法的使用:<button @click="methodName1"></button>
</div>