Vuex初体验

全局引入

main.js中引入

1
2
3
4
5
6
7
8
9
import 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
    34
    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)
    }
    }
    })

不过大家注意一点,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
    16
    actions: {
    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
41
import 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
2
3
4
5
6
7
8
9
10
// main.js
import store from './store/index'

new Vue({
el: '#app',
router,
components: {....},
template: '....',
store
})

之后记得在main.js之中引用哦

1
2
3
4
5
6
const module1 = {
state: {....},
mutations: {....},
....
}
export default module1

同时,如果你的业务分为多种模块,那么也可以在store文件夹下建立相应的js文件,将其暴露出来即可

1
2
3
4
5
6
7
8
9
10
11
12
import 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
7
computed:{
...mapState({
count: state=>{
return state.app.count
}
})
}

在这里插入图片描述