一、module的作用
由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。
為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:
二、module的使用方法
1、配置
- 項目結構
- 在index.js文件中進行組裝
import Vue from 'vue' import Vuex from 'vuex' import state from './state' import mutations from './mutations' import getters from './getters' import actions from './actions' import user from './modules/user' import rights from './modules/right' import roles from './modules/role' import homes from './modules/home' Vue.use(Vuex); //組裝模塊並導出 store 的地方 export default new Vuex.Store({ //根節點相關 state, mutations, getters, actions, //模塊相關 modules: { user, rights, roles, homes, }, });
- 在main.js的vue中進行注冊store
import router from './router' import store from './store/index' var vm = new Vue({ el: '#app', router, store, components: {App}, template: '<App/>' });
2、使用
- 以module文件夾中的user.js為例,如果建立的只是給固定的組件User組件使用,在user.js文件中使用命名空間
export default { namespaced: true,//使用命名空間,這樣只在局部使用 state: { }, mutations: { }, getters: { } }
- 在User組件中發送ajax請求,注意攜帶命名空間的名稱,也就是index.js組裝時使用的名字
created() { this.getUsers() }, methods:{ getUsers() { //將token設置在請求頭中提交,已經在攔截器中設置 // this.$http.defaults.headers.common['Authorization'] = localStorage.getItem("token"); this.$store.dispatch('user/getAllUserList', {_this: this, query: this.query})//this是Vue實例 }, }
- 在user.js文件中的action進行異步操作
//有命名空間提交方式,類似this.$store.dispatch("user/getAllUserList"); actions: { //將Vue實例進行傳遞接收 // getAllUserList(context, _this) { // //局部狀態通過 context.state 暴露出來,根節點狀態則為 context.rootState: //加入分頁 getAllUserList(context, object) { //局部狀態通過 context.state 暴露出來,根節點狀態則為 context.rootState: //發送get請求獲取API數據 crm/user?page=${context.state.page}&size=${context.state.size}&username=${object.query} object._this.$http.get(`crm/user?page=${context.state.page}&size=${context.state.size}`) .then((response) => { // handle success context.commit('GETALLUSER', response.data); object._this.$message.success("獲取數據成功") object._this.page=1 }) .catch((error) => { // handle error console.log(error); }) .finally(() => { // always executed }); // const response = await this.$http.get('crm/user'); // context.commit('GETALLUSER', response); }, }
- 在user.js的mutations中進行state值得修改
mutations: { //action中提交該mutation GETALLUSER(state, data) { state.UserList = data.results; //將添加成功的數據添加到狀態,用於頁面更新 state.Total = data.count }, }
當然,在此之前state是需要初始化的:
state: { UserList: [], Total: null, size: 2, query: null, page: 1, }
- 在getters中對state數據根據需求進行過濾
getters: { getUserList: state => { return state.UserList; } }
- 在User組件中通過computed方法獲取getters
import {mapGetters} from 'vuex' export default { name: "User", computed: { ...mapGetters({ UserList: 'user/getUserList', }), } }
這樣就可以在html中直接使用UserList屬性了。
三、action、mutation、getters的互相調用
1、actions中調用其它action
async delUser(context, object) { //context包含的參數:commit,dispatch,getters,rootGetters,rootState,state ... ... //刪除后刷新頁面 context.dispatch("getAllUserList", object._this) } },
在action中通過context.dispatch方法進行調用
2、getters中調用其它gerter
getters:{ getRolesList: state => { return state.RoleList; }, //調用其它getter getRoleIdList: (state, getters) => { let RoleIdArray = []; getters.getRolesList.forEach(item => { RoleIdArray.push(item.id); }); return RoleIdArray }, }
getters中可以傳入第二個參數就是getters,然后通過這樣使用其它getter。當然getters也可以傳入根節點狀態和getters。
getters: { // 在這個模塊的 getter 中,`getters` 被局部化了 // 你可以使用 getter 的第四個參數來調用 `rootGetters` someGetter (state, getters, rootState, rootGetters) { }, },
3、組件中獲取getters
(1)帶上命名空間訪問
getters['user/getUserList']
(2)通過輔助函數訪問(推薦)
import {mapGetters} from 'vuex' computed: { ...mapGetters({ UserList: 'user/getUserList', total: 'user/getTotal', DeptList: 'user/geDeptList', RoleList: 'user/getRolesList', RoleIdList: 'user/getRoleIdList', AllRoleList: 'user/getALLRolesList', AllRoleIdList: 'user/getAllRoleIdList', permissionDict: 'getPermission' }), }
4、組件中提交action
this.$store.dispatch('user/setRole', { _this: this, id: this.currentuser.id, rid_list: {roles: this.CheckedRolesIdList} })
如果是全局的就不需要加上局部命名空間user