1.概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

2.何时使用?

多个组件需要共享数据时

3.搭建vuex环境

1、创建文件src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}

//创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})

2、在main.js中创建vm时传入store配置项

......
//引入store
import store from './store'
......

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    store
})

4.基本使用

1、初始化数据、配置actions、配置mutations,操作文件store.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)

const actions = {
    //响应组件中加的动作
    jia(context,value){
        // console.log('actions中的jia被调用了',miniStore,value)
        context.commit('JIA',value)
    },
}

const mutations = {
    //执行加
    JIA(state,value){
        // console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    }
}

//初始化数据
const state = {
   sum:0
}

//创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})

2、组件中读取vuex中的数据:$store.state.sum

3、组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

求和案例_纯vue版

 1 <template>
 2     <div>
 3         <Count/>
 4     </div>
 5 </template>
 6 
 7 <script>
 8     import Count from './components/Count'
 9     export default {
10         name:'App',
11         components:{Count},
12     }
13 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{sum}}</h1>
 4         <select v-model.number="n">
 5             <option value="1">1</option>
 6             <option value="2">2</option>
 7             <option value="3">3</option>
 8         </select>
 9         <button @click="increment">+</button>
10         <button @click="decrement">-</button>
11         <button @click="incrementOdd">当前求和为奇数再加</button>
12         <button @click="incrementWait">等一等再加</button>
13     </div>
14 </template>
15 
16 <script>
17     export default {
18         name:'Count',
19         data() {
20             return {
21                 n:1, //用户选择的数字
22                 sum:0 //当前的和
23             }
24         },
25         methods: {
26             increment(){
27                 this.sum += this.n
28             },
29             decrement(){
30                 this.sum -= this.n
31             },
32             incrementOdd(){
33                 if(this.sum % 2){
34                     this.sum += this.n
35                 }
36             },
37             incrementWait(){
38                 setTimeout(()=>{
39                     this.sum += this.n
40                 },500)
41             },
42         },
43     }
44 </script>
45 
46 <style lang="css">
47     button{
48         margin-left: 5px;
49     }
50 </style>
Count.vue

求和案例_vuex版

 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 
 4 Vue.config.productionTip = false
 5 
 6 //引入store
 7 import store from './store/index'
 8 
 9 new Vue({
10   el:"#app",
11   render: h => h(App),
12   store, //简写
13   beforeCreate() {
14     //安装全局事件总线
15     Vue.prototype.$bus = this
16   },
17 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 //应用Vuex插件
 6 Vue.use(Vuex)
 7 
 8 //准备actions——用于响应组件中的动作
 9 const actions = {
10     // jia(context, value) {
11     //     // console.log('actions中的jia被调用了')
12     //     context.commit('JIA', value)
13     // },
14     // jian(context, value) {
15     //     // console.log('actions中的jian被调用了')
16     //     context.commit('JIAN', value)
17     // },
18     jiaOdd(context, value){
19         if (context.state.sum % 2){
20             context.commit('JIA',value)
21         }
22     },
23     jiaWait(context, value){
24         setTimeout(()=>{
25             context.commit('JIA',value)
26         },500)
27     }
28 }
29 //准备mutations——用于操作数据(state)
30 const mutations = {
31     JIA(state, value) {
32         // console.log('mutations中的jia被调用了')
33         state.sum += value
34     },
35     JIAN(state, value) {
36         // console.log('mutations中的jian被调用了')
37         state.sum -= value
38     }
39 }
40 //准备state——用于存储数据
41 const state = {
42     sum: 0 //当前的和
43 }
44 
45 export default new Vuex.Store({
46     actions,
47     mutations,
48     state
49 })
index.js
 1 <template>
 2     <div>
 3         <Count/>
 4     </div>
 5 </template>
 6 
 7 <script>
 8     import Count from './components/Count'
 9     export default {
10         name:'App',
11         components:{Count},
12     }
13 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{$store.state.sum}}</h1>
 4         <select v-model.number="n">
 5             <option value="1">1</option>
 6             <option value="2">2</option>
 7             <option value="3">3</option>
 8         </select>
 9         <button @click="increment">+</button>
10         <button @click="decrement">-</button>
11         <button @click="incrementOdd">当前求和为奇数再加</button>
12         <button @click="incrementWait">等一等再加</button>
13     </div>
14 </template>
15 
16 <script>
17     export default {
18         name:'Count',
19         data() {
20             return {
21                 n:1, //用户选择的数字
22             }
23         },
24         methods: {
25             increment(){
26         this.$store.commit('JIA',this.n)
27             },
28             decrement(){
29         this.$store.commit('JIAN',this.n)
30             },
31             incrementOdd(){
32         this.$store.dispatch('jiaOdd',this.n)
33             },
34             incrementWait(){
35         this.$store.dispatch('jiaWait',this.n)
36             },
37         },
38     }
39 </script>
40 
41 <style lang="css">
42     button{
43         margin-left: 5px;
44     }
45 </style>
Count.vue

5.getters的使用

1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
2. 在store.js中追加getters配置
   const getters = {
       bigSum(state){
           return state.sum * 10
       }
   }
   
   //创建并暴露store
   export default new Vuex.Store({
       ......
       getters
   })
3. 组件中读取数据:$store.getters.bigSum
 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 
 4 Vue.config.productionTip = false
 5 
 6 //引入store
 7 import store from './store/index'
 8 
 9 new Vue({
10   el:"#app",
11   render: h => h(App),
12   store, //简写
13   beforeCreate() {
14     //安装全局事件总线
15     Vue.prototype.$bus = this
16   },
17 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 //应用Vuex插件
 6 Vue.use(Vuex)
 7 
 8 //准备actions——用于响应组件中的动作
 9 const actions = {
10     // jia(context, value) {
11     //     // console.log('actions中的jia被调用了')
12     //     context.commit('JIA', value)
13     // },
14     // jian(context, value) {
15     //     // console.log('actions中的jian被调用了')
16     //     context.commit('JIAN', value)
17     // },
18     jiaOdd(context, value){
19         if (context.state.sum % 2){
20             context.commit('JIA',value)
21         }
22     },
23     jiaWait(context, value){
24         setTimeout(()=>{
25             context.commit('JIA',value)
26         },500)
27     }
28 }
29 //准备mutations——用于操作数据(state)
30 const mutations = {
31     JIA(state, value) {
32         // console.log('mutations中的jia被调用了')
33         state.sum += value
34     },
35     JIAN(state, value) {
36         // console.log('mutations中的jian被调用了')
37         state.sum -= value
38     }
39 }
40 //准备state——用于存储数据
41 const state = {
42     sum: 0 //当前的和
43 }
44 //准备getters——用于将state中的数据进行加工
45 const getters = {
46     bigSum(state){
47         return state.sum * 10
48     }
49 }
50 
51 export default new Vuex.Store({
52     actions,
53     mutations,
54     state,
55     getters
56 })
index.js
 1 <template>
 2     <div>
 3         <Count/>
 4     </div>
 5 </template>
 6 
 7 <script>
 8     import Count from './components/Count'
 9     export default {
10         name:'App',
11         components:{Count},
12     }
13 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{$store.state.sum}}</h1>
 4         <h3>当前求和放大10倍为:{{$store.getters.bigSum}}</h3>
 5         <select v-model.number="n">
 6             <option value="1">1</option>
 7             <option value="2">2</option>
 8             <option value="3">3</option>
 9         </select>
10         <button @click="increment">+</button>
11         <button @click="decrement">-</button>
12         <button @click="incrementOdd">当前求和为奇数再加</button>
13         <button @click="incrementWait">等一等再加</button>
14     </div>
15 </template>
16 
17 <script>
18     export default {
19         name:'Count',
20         data() {
21             return {
22                 n:1, //用户选择的数字
23             }
24         },
25         methods: {
26             increment(){
27         this.$store.commit('JIA',this.n)
28             },
29             decrement(){
30         this.$store.commit('JIAN',this.n)
31             },
32             incrementOdd(){
33         this.$store.dispatch('jiaOdd',this.n)
34             },
35             incrementWait(){
36         this.$store.dispatch('jiaWait',this.n)
37             },
38         },
39     }
40 </script>
41 
42 <style lang="css">
43     button{
44         margin-left: 5px;
45     }
46 </style>
Count.vue

6.四个map方法的使用

1. mapState方法:用于帮助我们映射state中的数据为计算属性
   computed: {
       //借助mapState生成计算属性:sum、school、subject(对象写法)
        ...mapState({sum:'sum',school:'school',subject:'subject'}),
            
       //借助mapState生成计算属性:sum、school、subject(数组写法)
       ...mapState(['sum','school','subject']),
   },
2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性
   computed: {
       //借助mapGetters生成计算属性:bigSum(对象写法)
       ...mapGetters({bigSum:'bigSum'}),
   
       //借助mapGetters生成计算属性:bigSum(数组写法)
       ...mapGetters(['bigSum'])
   },
3.mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数
   methods:{
       //靠mapActions生成:incrementOdd、incrementWait(对象形式)
       ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
   
       //靠mapActions生成:incrementOdd、incrementWait(数组形式)
       ...mapActions(['jiaOdd','jiaWait'])
   }
4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数
   methods:{
       //靠mapActions生成:increment、decrement(对象形式)
       ...mapMutations({increment:'JIA',decrement:'JIAN'}),
       
       //靠mapMutations生成:JIA、JIAN(对象形式)
       ...mapMutations(['JIA','JIAN']),
   }
备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

求和案例_mapState与mapGetters

 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 
 4 Vue.config.productionTip = false
 5 
 6 //引入store
 7 import store from './store/index'
 8 
 9 new Vue({
10   el:"#app",
11   render: h => h(App),
12   store, //简写
13   beforeCreate() {
14     //安装全局事件总线
15     Vue.prototype.$bus = this
16   },
17 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 //应用Vuex插件
 6 Vue.use(Vuex)
 7 
 8 //准备actions——用于响应组件中的动作
 9 const actions = {
10     // jia(context, value) {
11     //     // console.log('actions中的jia被调用了')
12     //     context.commit('JIA', value)
13     // },
14     // jian(context, value) {
15     //     // console.log('actions中的jian被调用了')
16     //     context.commit('JIAN', value)
17     // },
18     jiaOdd(context, value){
19         if (context.state.sum % 2){
20             context.commit('JIA',value)
21         }
22     },
23     jiaWait(context, value){
24         setTimeout(()=>{
25             context.commit('JIA',value)
26         },500)
27     }
28 }
29 //准备mutations——用于操作数据(state)
30 const mutations = {
31     JIA(state, value) {
32         // console.log('mutations中的jia被调用了')
33         state.sum += value
34     },
35     JIAN(state, value) {
36         // console.log('mutations中的jian被调用了')
37         state.sum -= value
38     }
39 }
40 //准备state——用于存储数据
41 const state = {
42     sum: 0, //当前的和
43     school:'京东',
44     subject:'前端'
45 }
46 //准备getters——用于将state中的数据进行加工
47 const getters = {
48     bigSum(state){
49         return state.sum * 10
50     }
51 }
52 
53 export default new Vuex.Store({
54     actions,
55     mutations,
56     state,
57     getters
58 })
index.js
 1 <template>
 2     <div>
 3         <Count/>
 4     </div>
 5 </template>
 6 
 7 <script>
 8     import Count from './components/Count'
 9     export default {
10         name:'App',
11         components:{Count},
12     }
13 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{sum}}</h1>
 4         <h3>当前求和放大10倍为:{{bigSum}}</h3>
 5     <h3>我在{{school}},学习{{subject}}</h3>
 6         <select v-model.number="n">
 7             <option value="1">1</option>
 8             <option value="2">2</option>
 9             <option value="3">3</option>
10         </select>
11         <button @click="increment">+</button>
12         <button @click="decrement">-</button>
13         <button @click="incrementOdd">当前求和为奇数再加</button>
14         <button @click="incrementWait">等一等再加</button>
15     </div>
16 </template>
17 
18 <script>
19   import {mapState,mapGetters} from 'vuex'
20 
21     export default {
22         name:'Count',
23         data() {
24             return {
25                 n:1, //用户选择的数字
26             }
27         },
28     computed:{
29       //靠程序员自己亲自去写计算属性
30       /* sum(){
31         return this.$store.state.sum
32       },
33       school(){
34         return this.$store.state.school
35       },
36       subject(){
37         return this.$store.state.subject
38       }, */
39 
40       //借助mapState生成计算属性,从state中读取数据。(对象写法)
41       // 对象中不能存在对象{x:1,y:2,{error}},...可将对象转化为键值对形式
42       // ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
43 
44       //借助mapState生成计算属性,从state中读取数据。(数组写法)
45       ...mapState(['sum','school','subject']),
46       // ######################################################
47       /* bigSum(){
48                 return this.$store.getters.bigSum
49             }, */
50       ...mapGetters({bigSum:'bigSum'}),
51       // ...mapGetters(['bigSum'])
52     },
53         methods: {
54             increment(){
55         this.$store.commit('JIA',this.n)
56             },
57             decrement(){
58         this.$store.commit('JIAN',this.n)
59             },
60             incrementOdd(){
61         this.$store.dispatch('jiaOdd',this.n)
62             },
63             incrementWait(){
64         this.$store.dispatch('jiaWait',this.n)
65             },
66         },
67 
68     }
69 </script>
70 
71 <style lang="css">
72     button{
73         margin-left: 5px;
74     }
75 </style>
Count.vue

求和案例_mapMutations与mapActions

 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 
 4 Vue.config.productionTip = false
 5 
 6 //引入store
 7 import store from './store/index'
 8 
 9 new Vue({
10   el:"#app",
11   render: h => h(App),
12   store, //简写
13   beforeCreate() {
14     //安装全局事件总线
15     Vue.prototype.$bus = this
16   },
17 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 //应用Vuex插件
 6 Vue.use(Vuex)
 7 
 8 //准备actions——用于响应组件中的动作
 9 const actions = {
10     // jia(context, value) {
11     //     // console.log('actions中的jia被调用了')
12     //     context.commit('JIA', value)
13     // },
14     // jian(context, value) {
15     //     // console.log('actions中的jian被调用了')
16     //     context.commit('JIAN', value)
17     // },
18     jiaOdd(context, value){
19         if (context.state.sum % 2){
20             context.commit('JIA',value)
21         }
22     },
23     jiaWait(context, value){
24         setTimeout(()=>{
25             context.commit('JIA',value)
26         },500)
27     }
28 }
29 //准备mutations——用于操作数据(state)
30 const mutations = {
31     JIA(state, value) {
32         // console.log('mutations中的jia被调用了')
33         state.sum += value
34     },
35     JIAN(state, value) {
36         // console.log('mutations中的jian被调用了')
37         state.sum -= value
38     }
39 }
40 //准备state——用于存储数据
41 const state = {
42     sum: 0, //当前的和
43     school:'京东',
44     subject:'前端'
45 }
46 //准备getters——用于将state中的数据进行加工
47 const getters = {
48     bigSum(state){
49         return state.sum * 10
50     }
51 }
52 
53 export default new Vuex.Store({
54     actions,
55     mutations,
56     state,
57     getters
58 })
index.js
 1 <template>
 2     <div>
 3         <Count/>
 4     </div>
 5 </template>
 6 
 7 <script>
 8     import Count from './components/Count'
 9     export default {
10         name:'App',
11         components:{Count},
12     }
13 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{sum}}</h1>
 4         <h3>当前求和放大10倍为:{{bigSum}}</h3>
 5     <h3>我在{{school}},学习{{subject}}</h3>
 6         <select v-model.number="n">
 7             <option value="1">1</option>
 8             <option value="2">2</option>
 9             <option value="3">3</option>
10         </select>
11         <button @click="increment(n)">+</button>
12         <button @click="decrement(n)">-</button>
13         <button @click="incrementOdd(n)">当前求和为奇数再加</button>
14         <button @click="incrementWait(n)">等一等再加</button>
15     </div>
16 </template>
17 
18 <script>
19   import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
20 
21     export default {
22         name:'Count',
23         data() {
24             return {
25                 n:1, //用户选择的数字
26             }
27         },
28     computed:{
29       //借助mapState生成计算属性,从state中读取数据。(对象写法)
30       // ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
31       //借助mapState生成计算属性,从state中读取数据。(数组写法)
32       ...mapState(['sum','school','subject']),
33       // ######################################################
34       ...mapGetters({bigSum:'bigSum'}),
35       // ...mapGetters(['bigSum'])
36     },
37         methods: {
38             // increment(){
39       //   this.$store.commit('JIA',this.n)
40             // },
41             // decrement(){
42       //   this.$store.commit('JIAN',this.n)
43             // },
44 
45       ...mapMutations({increment:'JIA',decrement:'JIAN'}),
46       // ...mapMutations(['JIA','JIAN']),
47 
48       //#########################################################
49 
50             // incrementOdd(){
51       //   this.$store.dispatch('jiaOdd',this.n)
52             // },
53             // incrementWait(){
54       //   this.$store.dispatch('jiaWait',this.n)
55             // },
56 
57       ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
58       // ...mapActions(['jiaOdd','jiaWait']),
59 
60         },
61 
62     }
63 </script>
64 
65 <style lang="css">
66     button{
67         margin-left: 5px;
68     }
69 </style>
Count.vue

7.求和案例_多组件共享数据

 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 
 4 Vue.config.productionTip = false
 5 
 6 //引入store
 7 import store from './store/index'
 8 
 9 new Vue({
10   el:"#app",
11   render: h => h(App),
12   store, //简写
13   beforeCreate() {
14     //安装全局事件总线
15     Vue.prototype.$bus = this
16   },
17 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 //应用Vuex插件
 6 Vue.use(Vuex)
 7 
 8 //准备actions——用于响应组件中的动作
 9 const actions = {
10     // jia(context, value) {
11     //     // console.log('actions中的jia被调用了')
12     //     context.commit('JIA', value)
13     // },
14     // jian(context, value) {
15     //     // console.log('actions中的jian被调用了')
16     //     context.commit('JIAN', value)
17     // },
18     jiaOdd(context, value){
19         if (context.state.sum % 2){
20             context.commit('JIA',value)
21         }
22     },
23     jiaWait(context, value){
24         setTimeout(()=>{
25             context.commit('JIA',value)
26         },500)
27     }
28 }
29 //准备mutations——用于操作数据(state)
30 const mutations = {
31     JIA(state, value) {
32         // console.log('mutations中的jia被调用了')
33         state.sum += value
34     },
35     JIAN(state, value) {
36         // console.log('mutations中的jian被调用了')
37         state.sum -= value
38     },
39     ADD_PERSON(state,value){
40         state.personList.unshift(value)
41     }
42 }
43 //准备state——用于存储数据
44 const state = {
45     sum: 0, //当前的和
46     school:'京东',
47     subject:'前端',
48     personList:[
49         {id:'001',name:'张三'}
50     ]
51 }
52 //准备getters——用于将state中的数据进行加工
53 const getters = {
54     bigSum(state){
55         return state.sum * 10
56     }
57 }
58 
59 export default new Vuex.Store({
60     actions,
61     mutations,
62     state,
63     getters
64 })
index.js
 1 <template>
 2     <div>
 3     <Count></Count>
 4     <hr>
 5     <Person></Person>
 6     </div>
 7 </template>
 8 
 9 <script>
10     import Count from './components/Count'
11     import Person from './components/Person'
12 
13     export default {
14         name:'App',
15         components:{Count,Person},
16     }
17 </script>
App.vue
 1 <template>
 2   <div>
 3     <h1>人员列表</h1>
 4     <h3 style="color:red">Count组件求和为:{{sum}}</h3>
 5     <input type="text" placeholder="请输入名字" v-model="name">
 6     <button @click="add">添加</button>
 7     <ul>
 8       <li v-for="p in personList" :key="p.id">{{p.name}}</li>
 9     </ul>
10   </div>
11 </template>
12 
13 <script>
14 import {nanoid} from 'nanoid'
15 
16 export default {
17   name: "Person",
18   data(){
19     return {
20       name:''
21     }
22   },
23   computed:{
24     personList(){
25       return this.$store.state.personList
26     },
27     sum(){
28       return this.$store.state.sum
29     }
30   },
31   methods:{
32     add(){
33       const personObj = {id:nanoid(),name:this.name}
34       this.$store.commit('ADD_PERSON',personObj)
35       this.name = ''
36     }
37   }
38 }
39 </script>
40 
41 <style scoped>
42 
43 </style>
Person.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{sum}}</h1>
 4         <h3>当前求和放大10倍为:{{bigSum}}</h3>
 5     <h3>我在{{school}},学习{{subject}}</h3>
 6     <h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3>
 7         <select v-model.number="n">
 8             <option value="1">1</option>
 9             <option value="2">2</option>
10             <option value="3">3</option>
11         </select>
12         <button @click="increment(n)">+</button>
13         <button @click="decrement(n)">-</button>
14         <button @click="incrementOdd(n)">当前求和为奇数再加</button>
15         <button @click="incrementWait(n)">等一等再加</button>
16     </div>
17 </template>
18 
19 <script>
20   import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
21 
22     export default {
23         name:'Count',
24         data() {
25             return {
26                 n:1, //用户选择的数字
27             }
28         },
29     computed:{
30       // ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
31       ...mapState(['sum','school','subject','personList']),
32 
33       ...mapGetters({bigSum:'bigSum'}),
34       // ...mapGetters(['bigSum'])
35     },
36         methods: {
37       ...mapMutations({increment:'JIA',decrement:'JIAN'}),
38       // ...mapMutations(['JIA','JIAN']),
39 
40       ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
41       // ...mapActions(['jiaOdd','jiaWait']),
42         },
43     }
44 </script>
45 
46 <style lang="css">
47     button{
48         margin-left: 5px;
49     }
50 </style>
Count.vue

8.模块化+命名空间

1. 目的:让代码更好维护,让多种数据分类更加明确。
2. 修改store.js
const countAbout = {
  namespaced:true,//开启命名空间
  state:{x:1},
  mutations: { ... },
  actions: { ... },
  getters: {
    bigSum(state){
       return state.sum * 10
    }
  }
}

const personAbout = {
  namespaced:true,//开启命名空间
  state:{ ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    countAbout,
    personAbout
  }
})
3. 开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
4. 开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
5. 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
6. 开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
 1 //引入Vue
 2 import Vue from 'vue'
 3 //引入App
 4 import App from './App.vue'
 5 //引入插件
 6 import vueResource from 'vue-resource'
 7 //引入store
 8 import store from './store'
 9 
10 //关闭Vue的生产提示
11 Vue.config.productionTip = false
12 //使用插件
13 Vue.use(vueResource)
14 
15 //创建vm
16 new Vue({
17     el:'#app',
18     render: h => h(App),
19     store,
20     beforeCreate() {
21         Vue.prototype.$bus = this
22     }
23 })
main.js
 1 //该文件用于创建Vuex中最为核心的store
 2 import Vue from 'vue'
 3 //引入Vuex
 4 import Vuex from 'vuex'
 5 
 6 import countOptions from './count'
 7 import personOptions from './person'
 8 
 9 //应用Vuex插件
10 Vue.use(Vuex)
11 
12 //创建并暴露store
13 export default new Vuex.Store({
14     modules:{
15         countAbout:countOptions,
16         personAbout:personOptions
17     }
18 })
index.js
 1 //求和相关的配置
 2 export default {
 3     namespaced:true,
 4     actions:{
 5         jiaOdd(context,value){
 6             console.log('actions中的jiaOdd被调用了')
 7             if(context.state.sum % 2){
 8                 context.commit('JIA',value)
 9             }
10         },
11         jiaWait(context,value){
12             console.log('actions中的jiaWait被调用了')
13             setTimeout(()=>{
14                 context.commit('JIA',value)
15             },500)
16         }
17     },
18     mutations:{
19         JIA(state,value){
20             console.log('mutations中的JIA被调用了')
21             state.sum += value
22         },
23         JIAN(state,value){
24             console.log('mutations中的JIAN被调用了')
25             state.sum -= value
26         },
27     },
28     state:{
29         sum:0, //当前的和
30         school:'京东',
31         subject:'前端',
32     },
33     getters:{
34         bigSum(state){
35             return state.sum*10
36         }
37     },
38 }
count.js
 1 //人员管理相关的配置
 2 import axios from 'axios'
 3 import { nanoid } from 'nanoid'
 4 export default {
 5     namespaced:true,
 6     actions:{
 7         addPersonWang(context,value){
 8             if(value.name.indexOf('王') === 0){
 9                 context.commit('ADD_PERSON',value)
10             }else{
11                 alert('添加的人必须姓王!')
12             }
13         },
14         addPersonServer(context){
15             axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
16                 response => {
17                     context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
18                 },
19                 error => {
20                     alert(error.message)
21                 }
22             )
23         }
24     },
25     mutations:{
26         ADD_PERSON(state,value){
27             console.log('mutations中的ADD_PERSON被调用了')
28             state.personList.unshift(value)
29         }
30     },
31     state:{
32         personList:[
33             {id:'001',name:'张三'}
34         ]
35     },
36     getters:{
37         firstPersonName(state){
38             return state.personList[0].name
39         }
40     },
41 }
person.js
 1 <template>
 2     <div>
 3         <Count/>
 4         <hr>
 5         <Person/>
 6     </div>
 7 </template>
 8 
 9 <script>
10     import Count from './components/Count'
11     import Person from './components/Person'
12 
13     export default {
14         name:'App',
15         components:{Count,Person},
16         mounted() {
17             // console.log('App',this)
18         },
19     }
20 </script>
App.vue
 1 <template>
 2     <div>
 3         <h1>人员列表</h1>
 4         <h3 style="color:red">Count组件求和为:{{sum}}</h3>
 5         <h3>列表中第一个人的名字是:{{firstPersonName}}</h3>
 6         <input type="text" placeholder="请输入名字" v-model="name">
 7         <button @click="add">添加</button>
 8         <button @click="addWang">添加一个姓王的人</button>
 9         <button @click="addPersonServer">添加一个人,名字随机</button>
10         <ul>
11             <li v-for="p in personList" :key="p.id">{{p.name}}</li>
12         </ul>
13     </div>
14 </template>
15 
16 <script>
17     import {nanoid} from 'nanoid'
18     export default {
19         name:'Person',
20         data() {
21             return {
22                 name:''
23             }
24         },
25         computed:{
26             personList(){
27                 return this.$store.state.personAbout.personList
28             },
29             sum(){
30                 return this.$store.state.countAbout.sum
31             },
32             firstPersonName(){
33                 return this.$store.getters['personAbout/firstPersonName']
34             }
35         },
36         methods: {
37             add(){
38                 const personObj = {id:nanoid(),name:this.name}
39                 this.$store.commit('personAbout/ADD_PERSON',personObj)
40                 this.name = ''
41             },
42             addWang(){
43                 const personObj = {id:nanoid(),name:this.name}
44                 this.$store.dispatch('personAbout/addPersonWang',personObj)
45                 this.name = ''
46             },
47             addPersonServer(){
48                 this.$store.dispatch('personAbout/addPersonServer')
49             }
50         },
51     }
52 </script>
Person.vue
 1 <template>
 2     <div>
 3         <h1>当前求和为:{{sum}}</h1>
 4         <h3>当前求和放大10倍为:{{bigSum}}</h3>
 5         <h3>我在{{school}},学习{{subject}}</h3>
 6         <h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3>
 7         <select v-model.number="n">
 8             <option value="1">1</option>
 9             <option value="2">2</option>
10             <option value="3">3</option>
11         </select>
12         <button @click="increment(n)">+</button>
13         <button @click="decrement(n)">-</button>
14         <button @click="incrementOdd(n)">当前求和为奇数再加</button>
15         <button @click="incrementWait(n)">等一等再加</button>
16     </div>
17 </template>
18 
19 <script>
20     import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
21     export default {
22         name:'Count',
23         data() {
24             return {
25                 n:1, //用户选择的数字
26             }
27         },
28         computed:{
29             //借助mapState生成计算属性,从state中读取数据。(数组写法)
30             ...mapState('countAbout',['sum','school','subject']),
31             ...mapState('personAbout',['personList']),
32             //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
33             ...mapGetters('countAbout',['bigSum'])
34         },
35         methods: {
36             //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
37             ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
38             //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
39             ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
40         },
41         mounted() {
42             console.log(this.$store)
43         },
44     }
45 </script>
46 
47 <style lang="css">
48     button{
49         margin-left: 5px;
50     }
51 </style>
Count.vue

 

posted on 2023-07-09 20:56  晨曦生辉耀匕尖  阅读(9)  评论(0编辑  收藏  举报