理解 vuex
vuex 的定义
- 专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
Vuex 原理
搭建 Vuex 开发环境
- 下载 Vuex
- 引入并使用 Vuex
vue.use(Vuex)
- 传入 stroe 配置项
配置 stroe 文件
- 此时,vm 和所有的组件都可以调用
$store
,它包含了操作数据所需要的所有 api
使用 vuex 重构一个小案例
先来看一个实现各种简单计算的 vue 组件
- 一个标题用来显示当前的计算结果
- 左边一个 select 选择框,用来指定每次计算用到的数值;四个按钮功能分别为加法、减法、当前计算结果为奇数时再做加法,以及等一秒钟之后再做加法
代码如下
现在我们从模型图中的 state 出发,开始改造
-
将最终要显示的数据(sum)交给state
-
从第一个按钮的函数里,调用
dispatch
,告诉 actions,接下来要执行的操作(add),并且将执行操作需要的数据(this.number)传递过去 -
在 store 文件中的 actions 里面,定义执行操作的
add
函数,函数可以接收两个参数,第一个是一个精简的$store
,它包含了dispatch
、commit
等 api;第二个参数为执行操作需要的数据(this.number)。并在add
函数里调用commit
-
ADD
大写是为了区分 actions 和 mutations 里的add
至此,actions 的任务完成,进入 mutations
-
在 mutations 中定义
ADD
函数,函数可以接收两个参数,第一个为存储数据用的state
,第二个为执行操作需要的数据(this.number)
然后在组件中读取 state 中的数据,整个流程结束,其他三个功能同理
- 有一点值得一提,就是所有的业务逻辑(包括 Ajax 请求),都应该放在 actions 里面。所以代码改造后的
奇数判断
、定时器
,都应该在 actions 里面,代码如下
完善
-
以上说过,actions 里面是处理业务逻辑的,那么开始定义的两个函数:
add
和sub
就显得很多余,因为它不包含任何的业务逻辑。对于这种情况,vuex 支持直接从组件中对话 mutations,跳过 actions
vuex 中的 getters
-
该配置项用来对 state 中的数据进行加工,以供其他组件
复用
-
getters 中可以直接定义函数,函数的参数为
state
,并以返回值来获得函数的执行结果 -
我们将以上案例增加一个功能,即可以显示最终计算结果再乘以十的结果
-
在组件的模板中增加一个三级标题用来显示乘以十的结果
-
配置 getters,并定义一个使结果乘以 10 的函数
-
在组件的模板中通过
$store
获得 getters 中的返回值
-
代码优化
- 解决模板在获取数据时,代码过长的问题
-
在获取 state 中的数据 sum 时,模板中使用了
$store.state.sum
,我们可以通过使用计算属性 computed 来实现在模板中只用写sum
就可以获取数据 -
这样很方便,但如果 state 中还有其他更多的数据需要获取,那就要重复定义更多个 computed,代码依然冗余。所以 vuex 提供了
mapState
来生成这些计算属性。 -
mapState
的返回值是一个包含了一个或多个 computed 函数的对象
。我们需要将要定义的函数名,以及要获取的数据,以对象的形式通过参数传递给它。它就可以帮我们生成 computed 函数 -
当我们需要生成的函数的函数名和要获取数据的变量名相同时,
mapState
还可以写成数组的格式,它看起来会更简洁 -
同样的,vuex 也提供了用于从 getters 里面获取数据的
mapGetters
,使用方法和mapState
一样,最终代码改造是这样的
-
- methods 代码优化
mapMutations
和mapActions
mapMutations
用来生成调用 commit 的方法,mapActions
用来生成调用 dispatch 的方法- 用法和 mapState 大同小异,将要生成的函数名和要调用的函数名当作参数以对象的方式传递
- 经过改造的 methods 最终代码为
- 同样的,
mapMutations
和mapActions
也有数组的写法 - 要执行操作的数据,要在模板绑定事件时以参数的方式传递
- 最终完成的代码