全局引入
main.js
中引入1
2
3
4
5
6
7
8
9import Vuex from 'vuex
Vue.use(Vuex)
new Vue({
el: '#app',
router,
components:{...},
template: '...',
store
})
创建
- state 用来数据共享数据存储
- mutation 用来注册改变数据状态
- getters 用来对共享数据进行过滤操作
- action 解决异步改变共享数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34const store = new Vuex.Store({
// 全局状态
state: {
count: 0
},
// 修改state的必要途径
mutations: {
increment(state, n) {
// 传入参数state是对state部分的引用
state.count += n
},
decrement(state, n) {
state.count -= n
}
},
// 只读属性,存放过滤方法
getters: {
myCount(state){
return `current count is ${state.count}`
}
},
// 存放业务逻辑
actions: {
myIncrease(context, obj){
context.commit('increment', 4)
},
myDecrease(context){
context.commit('decrement', 2)
}
}
})
不过大家注意一点,actions
中我们引用mutations
中的方法时用到了 commit
,它就像Vue中的$emit
一样,用于发布任务,而mutations
中的方法则监听调用自己的地方,时刻准备为其服务
组件引入
1 | imoprt { mapState } from 'vuex |
- 我们通过
computed
属性进行实时监测(本例中使用解构赋值)。如此就可以在页面中使用state
中的值了。 - 而方法的传递则需要我们进行
commit
调用。当然使用this.methodName()
调用亦可1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35<template>
<button @click="increase">Add</button>
<button @click="decrease">Minus</button>
</template>
<script>
import {mapMutations, mapActions, mapState, mapGetter}
export default{
......
computed: {
...mapState(['count'])
},
methods: {
// 声明引入actions和mutations中的方法
...mapMutations(['increment', 'decrement']),
...mapActions(['myIncrease', 'myDecrease']),
async increse(){
const products = await
this.$store.commit('increment', 1)
// this.increment(1) 亦可
// this.$store.state.count++
// this.myIncrease({id: 123})
},
async decrese(){
const products = await
this.$store.commit('decrement', 2)
// this.decrement(2) 亦可
// this.$store.state.count--
// this.myDecrease()
}
}
}
</script>
上面列举的三种方法传递的方法中,我们发现通过this.$store.state.count++
方式调用时无法令Detected Vue
记录,因为他跳过了mutation
直接对state
数据进行操作,自然无法进行记录
- 如果你仅仅是想完成count的加减,我推荐你使用
action
。毕竟是逻辑代码,更方便读者理解。真正的使用方式比如通过此方式从后台调用数据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16actions: {
async myIncrease(context) {
context.commit('increment') // 调用mutations中的increment方法
const products = await axios.get(......)
return products
}
}
// component
methods: {
...mapActions(['myIncrease', 'myDecrease']),
async increase(){
const products = await this.myIncrease();
// do Some Thing
}
}
封装
我们将Vuex的实例放在main.js
中显然不是明智之举,所以我们不妨新建一个store
文件夹,将其主题存至store
中的index.js
中(如此一来我们只需要引入./store/index
即可完成)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 全局状态
state: {
count: 0
},
// 修改state的必要途径
mutations: {
increment(state, n) {
// 传入参数state是对state部分的引用
state.count += n
},
decrement(state, n) {
state.count -= n
}
},
// 只读属性,存放过滤方法
getters: {
myCount(state){
return `current count is ${state.count}`
}
},
// 存放业务逻辑
actions: {
myIncrease(context, obj){
context.commit('increment', 4)
},
myDecrease(context){
context.commit('decrement', 2)
}
}
})
export default store
1 | // main.js |
之后记得在main.js
之中引用哦1
2
3
4
5
6const module1 = {
state: {....},
mutations: {....},
....
}
export default module1
同时,如果你的业务分为多种模块,那么也可以在store
文件夹下建立相应的js文件,将其暴露出来即可1
2
3
4
5
6
7
8
9
10
11
12import Module1 from './module1'
import Module2 from './module2'
Vue.use(Vuex)
const store = new Vuex.Store({
modules:{
Module1, Module2
}
})
export default store
而同时,在组建之中我们需要用隐射调用1
2
3
4
5
6
7computed:{
...mapState({
count: state=>{
return state.app.count
}
})
}