Fork me on GitHub

Vuex学习日记

vuex状态管理

学习vue全家桶中的状态管理工具 —— Vuex

挺久之前就开始学习vue了,vue全家桶中的vuex也有稍微了解,但是那个时候还没有对其进行更熟悉的了解吧,今天就重新认真学习了下。

看看官方对Vuex的解释,

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

在学习之后,个人对其也有了自己的理解,我觉得可以理解为在data中的属性需要共享给其他vue组件使用的部分。简单的说就是data中需要共用的属性。比如做一个购物车,那么购物车的内容就需要在不同页面中进行保留和传递,这时候就可以使用Vuex对其进行集中管理。在此之前,我们都是用父子组件互相传值来完成的。

在官方文档中,会学到 Vue 的一些核心概念,深入理解所有的概念对于使用 Vuex 来说是必要的。
接下来我自己通过一个小案例来弄清楚这些核心概念,当做一个总结了。

起步

第一步先通过vue-cli脚手架工具搭建起vue项目运行的环境,这里就不多说了。
接着通过npm安装vuex。本人用的是VScode,所以自带了终端,直接ctrl+`打开终端,输入下面命令行:

1
npm install vuex --save

vuex在开发过程需要用到,所以必须加上--save选项。

接着新建store.js文件,将vue和vuex导入,并且使用vuex。

1
2
3
4
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

接着创建一个仓库state(我自己的理解 - -),再放入一个变量count。(做一个小计数器)

1
2
3
4
//state理解为存放共享状态的仓库
const state = {
count: 1
}

然后将内容导出:

1
2
3
export default new Vuex.Store({
state
})

state

在component文件夹下创建Count.vue模板文件。

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
<template>
<div>
<h2>{{msg}}</h2><hr/>
<h3>{{$store.state.count}} --- {{count}}</h3>
</div>
</template>

<script>
import store from '../vuex/store.js';
//解构赋值得到mapState
import { mapState } from 'vuex';
export default {
data() {
return {
msg: 'Hello Vuex'
}
},
//利用mapState方法可以简化拼写,如$store.state.count简化为count
//最容易理解的写法为:
// computed: {
// count() {
// return this.$store.state.count;
// }
// },
computed: {
...mapState(['count'])
},
store
}
</script>

<style lang="">

</style>

一开始就需要引入并注册store,这点很重要。
其中利用mapState辅助函数帮助我们生成计算属性。如上HTML代码中的$store.state.count可以通过mapState直接简化为count。只需从vuex中解构赋值得到mapState,再在computed中做映射。由于mapState 函数返回的是一个对象,所以可以通过ES6新增的对象展开运算符...将它与局部计算属性混合使用。

mutations

接下来为计数器增加两个按钮,一加一减。Count.vue中的HTML代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div>
<h2>{{msg}}</h2><hr/>
<h3>{{$store.state.count}} --- {{count}}</h3>
<!--新增-->
<p>
<button @click="$store.commit('add',5)">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
<!--新增-->
</div>
</template>

上面增加了两个方法add和reduce,接下来在store.js中分别实现:

1
2
3
4
5
6
7
8
9
//mutations用于改变state中的状态值
const mutations = {
add(state, n) {
state.count += n;
},//可传第二个参数
reduce(state) {
state.count--
},
}

可以看到,这里使用mutations。更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,即上面可见的,需要调用$store.commit()方法。参数则为函数。同时也要像前面state一样,导出mutations。

如果我们希望直接通过@click='add()'这样就可以直接调用方法,而不需要利用$store.commit()时,我们可以使用mapMutations。
在Count.vue中,同理先从vuex中解构赋值得到mapMutations,然后在methods中进行方法的映射:

1
2
//将this.add()和this.reduce()分别映射为this.$store.commit('add')和this.$store.commit('reduce')
methods: mapMutations(['add', 'reduce']),

此时,在Count.vue中我们便可以直接调用函数,跟没引用vuex插件一样。

1
2
<button @click="add">+</button>
<button @click="reduce">-</button>

getters

接着是getters。getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。你可以把它看作store.js的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

在store.js做如下操作:

1
2
3
4
5
6
//getters用于计算过滤
const getters = {
count: (state) => {
return state.count += 100;
}
}

同时导出getters。
接着先从vuex中解构赋值得到mapGetters,然后computed中,同理使用扩展运算符:

1
2
3
computed: {
...mapGetters(['count'])
}

此时跟普通Vue实例中的computed一样,当需要被计算的值发送变化时,计算属性先做出变化,改变当前的值。

在学习的过程中还有两个概念——actionmodule

action : actions和之前讲的mutations功能基本一样,不同点是,actions是异步的改变state状态,而mutations是同步改变状态。

module : 状态管理器的模块组操作。随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。

这里有空的话会再去看官方文档或者技术胖的博客,进行一个更系统的学习。