我們現在學習的store.js文件是一個單一的數據模塊類型,如果此時我們項目特別的龐大,比如我們有新聞、體育、科學等等模塊,這些模塊都有自己的全局數據,此時如果都放到store.js的state中,不好維護
所以我們可以通過module進行進行結構、模塊的拆分
基本使用
我們在store.js文件中對結構進行了改造
store.js文件
1 import Vuex from 'vuex' 2 // 引入vue 3 import Vue from 'vue' 4 // 使用vuex 5 Vue.use(Vuex) 6 const moduleA = { 7 state: { str: '模塊A' }, 8 mutations: {}, 9 actions: {}, 10 getters: {} 11 } 12 const moduleB = { 13 state: { str: '模塊B' }, 14 mutations: {}, 15 actions: {}, 16 getters: {} 17 } 18 const moduleC = { 19 state: { str: '模塊C' }, 20 mutations: {}, 21 actions: {}, 22 getters: {} 23 } 24 25 export default new Vuex.Store({ 26 modules: { 27 a: moduleA, 28 b: moduleB, 29 c: moduleC 30 } 31 })
main.js文件
1 import Vue from 'vue' 2 // 相對路徑引入的App.vue文件 3 import App from './App.vue' 4 // 引入store文件 5 import store from './store/store.js' 6 7 8 new Vue({ 9 // 渲染節點 10 render: h => h(App), 11 // 掛載store文件 12 store:store 13 }).$mount('#app')
上面的代碼就是一個拆分模塊縮小版
任意頁面使用
1 <template> 2 <div> 3 {{$store.state.a.str}} 4 5 </div> 6 </template> 7 8 <script> 9 export default { 10 11 } 12 </script> 13 14 <style lang="scss" scoped> 15 16 </style>
我們上面的module拆分是不完整的,引入還是獨立在store.js文件中,所以我們通常都是將多個模塊進行文件的獨立拆分
比如news模塊news.js
比如user模塊user.js
比如sports模塊sports.js
我們以news.js文件為例
news.js文件
1 export default{ 2 state:{ 3 str:"我是新聞模塊" 4 }, 5 mutations:{ 6 7 }, 8 actions:{ 9 10 }, 11 }
此時store.js要分別引入這些模塊文件,並進行module注冊
1 import Vuex from 'vuex' 2 // 引入vue 3 import Vue from 'vue' 4 // 使用vuex 5 Vue.use(Vuex) 6 //引入相關的store模塊 7 import news from "./news.js" 8 import user from "./user.js" 9 import sport from "./sport.js" 10 11 12 export default new Vuex.Store({ 13 modules: { 14 user, 15 sport, 16 news, 17 } 18 })
App.vue
1 <template> 2 <div> 3 <p>{{$store.state.news.str}}</p> 4 <p> {{$store.state.sport.str}}</p> 5 <p>{{$store.state.user.str}}</p> 6 </div> 7 </template> 8 9 <script> 10 export default { 11 } 12 </script> 13 14 <style lang="scss" scoped> 15 16 </style>
此時遇到了一個難題,除了state有自己的獨立的命名空間外,其他的還是共享一個空間,比如我們給user.js設置了一個mutations為add,給new.js也設置了一個add
此時由於擁有的都是共享的空間,會造成數據混亂
news.js
1 export default { 2 state: { 3 num: 100 4 }, 5 mutations: { 6 add(state) { 7 state.num++ 8 } 9 }, 10 actions: { 11 12 } 13 }
user.js
1 export default { 2 state: { 3 num: 100 4 }, 5 mutations: { 6 add(state) { 7 state.num += 5 8 } 9 }, 10 actions: { 11 12 } 13 }
在頁面中使用
1 <template> 2 <div> 3 <p>我是user{{$store.state.user.num}}</p> 4 <p>我是news{{$store.state.news.num}}</p> 5 <button @click='add'>按我加1</button> 6 </div> 7 </template> 8 <script> 9 export default { 10 methods:{ 11 add(){ 12 this.$store.commit("add") 13 } 14 } 15 } 16 </script> 17 18 <style lang="scss" scoped> 19 20 </style>
此時頁面中的兩個num都發生了變化
此時我們可以看到user和news中的數據都會發生改變
我們工作避免不了會設置同名的命名,怎么避免?
我們可以給每一個store的js文件都設置自己的namespaced,值為true就代碼設置獨立模塊,每一個模塊的mutations,actions,getters都是獨立的不是共享的
比如我們new.js文件中設置namespaced
1 export default { 2 namespaced: true, 3 state: { 4 num: 100 5 }, 6 mutations: { 7 add(state) { 8 state.num++ 9 } 10 }, 11 actions: { 12 13 } 14 }
此時如果我們想讓news頁面的數據發生改變,比如改變commit的傳參方法
1 methods: { 2 add() { 3 this.$store.commit('news/add') 4 } 5 }
如果加了namespaced為true后,使用commit就必須加對應的命名空間
和commit一樣,如果是actions也是通過添加對應的命名空間進行使用
1 add() { 2 this.$store.dispatch('news/addServer') 3 }
getters也是一樣,只不過使用方法有一些不一樣,方括號內部設置對應命名空間
1 <p>奇偶性:{{$store.getters['news/jox']}}</p>