我们现在学习的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>