VueX的使用
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。其思想借鉴于Flux, Redux。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
介绍: VueX是什么
为什么要使用Vuex
所谓的状态管理模式的状态,可以理解为一组通过 Vuex 进行维护的全局变量。一些用户的个人参数,亦或是多组件共同维护的prop。为了正确维护这些参数,可以使用数据库进行存储,也可以在各类组件之间多次传递。虽然方法可行,但在维护的过程中,可以明显感受非常麻烦。此时使用 Vuex 来进行存储与维护,很容易就能化繁为简。当然,Vuex 并不适合用于比较小型的应用。
引入Vuex
安装
vue-cli项目引入vuex
Vuex核心概念
state 用于共享数据存储
getter 用于对共享数据进行处理操作
mutation 用于注册改变数据状态
action 解决异步改变共享数据
module 数据维护模块化
从项目的角度考虑,可以将这五大核心分别进行维护,由于 module 相对于其他特征有所区别,所以先不进行引入。
State
数据存储的位置,对象类型直接维护数据
定义
使用
由于store已在Vue实例上进行全局挂载,所以我们可以直接获取到state中所储存的数据,其中this指向Vue实例。可以配合computed计算属性使用,或者在加载组件时进行赋值。
如果有安装vue-devtool,可以在其中Vuex的Tab页直接看到state所储存的数据。
mapState函数
对于state内数据进行实时的监听和使用,很容易想到计算属性computed,比如
这样通过计算属性获取与msg同名的state.msg属性,就显得有些冗余了,在参数较少的情况下可能没什么感觉,但在参数多的情况下就会显得非常麻烦,所以我们可以使用mapState函数简化这个过程
getter
对state中的数据做统一的处理操作,但并不改变数据本身
如果没有getter,我们要对state的数据进行一些譬如筛选的操作,可以直接对数据进行
由于state中的参数本身具有全局变量的特征,所以常常不止一处会对其进行一些操作,如果这些操作方法类似或者相同,那代码就会显得有些冗余,这个时候就可以使用getter来维护这些方法
定义
使用
getter更类似于Vue中的计算属性computed,是state经过某种处理后的储存数据。它所返回的结果会被缓存起来,直到它所依赖的状态数据被改变后才会重新调用进行计算,也因而getter并不能改变state的数据本身。
mapGetter函数
与mapState一样,mapGetter也是出于对于代码简化的角度所考虑使用的。由于getter本身不对state数据做修改,其处理效果所返回的结果也与state一样会在计算属性中被使用,所以mapGetter的使用效果与mapState极为类似
mutation
通过在mutation内注册方法,可以对state内的数据进行修改
数据修改处理就与字面意思一样容易理解了,我们可以在mutation内定义修改方法来操作state的数据。
定义
使用
mapMutations函数
mutations中同样有简化代码的方法mapMutations,与mapGetters不同之处在于,mutations本身都是修改state数据的方法,所以mapMutations多为在methods属性内使用
mutation有一个特别要注意的点是,只能使用同步方法,不可异步操作数据,任何异步操作都不会在mutations内生效。那么为了解决异步操作的问题,action就应运而生了。
action
功能与mutation类似,但用于储存异步方法
在mutation中,我们也提到了异步方法需要action来进行处理,而同步方法已在mutation中处理,所以一般我们可以在action中编写异步逻辑,然后调用mutation中的同步方法,通过混用来达到action需要达到的效果。
定义
使用
总体来说就是以 action -> mutation -> state 的形式进行调用。但由于满足异步处理,所以Promise与async/await自然也是可以在这里进行使用的,dispatch方法可以返回一个Promise类型来处理异步。
返回Promise的action
当然也可以这样写
使用async/await组合多个action
mapActions的使用方法与mapMutation类似,就不再具体写示例。
module
可使vuex根据业务需要分割成多个子系统模块,分别来进行维护。当然子模块也可以继续套更小的模块,层层嵌套可以构成一棵由模块构成的状态树。
使用
对于单一模块来说,getter,mutation等的state参数都指向当前模块的state,action则通过conext.state获得
命名空间
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
也就是说,假设现有两个模块 moduleA 和 moduleB,两者有一个重名的 mutation 记为 mutation1,那么当我们使用这个 mutation 时,moduleA 和 moduleB 的对应 state 都回发生改变,这也就是所谓的在全局命名空间下,mutation被注册的含义。当然 action 同理。
如果通过改变某个模块下命名空间的属性 namespaced 为 true 的方式使其成为带命名空间的模块。模块对应的getter、mutation、action 也会对应注册至该命名空间下。
★ state需要与这些相区别,state作为入参时,不论是否启用命名空间,都为当前模块的state
我们来看官方给的一个例子
将模块想象成一棵模块树,根节点为全局命名空间,每个模块就是一个子节点,如果当前节点没有命名空间,那么它所属的命名空间就从当前节点的父辈节点往上找。
启用了命名空间的 getter 和 action 会收到局部化的 getter,dispatch 和 commit。也就是说,你在使用模块内容(module assets)时,不会再因为入参的getters是注册在全局空间下,而需要在同一模块内额外添加空间名前缀。
局部命名空间访问全局内容(Global Asset)
如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。
在局部命名空间注册全局action
若需要在带命名空间的模块注册全局 action,则可添加 root: true,并将这个 action 的定义放在函数 handler 中,类似深度监听Object的写法。
带命名空间使用绑定方法
带命名空间使用mapState、mapActions等方法时,难免会碰到前缀过长,或是命名空间路径比较长的情况,我们可以将部分命名空间提出为第一个参数来进行使用。
也可以通过 createNamespacedHelpers 辅助,让绑定方法更加简单,这对实际编写系统来说,用处也是极大的。
结语
Vuex可以说是Vue中相当重要的一块内容。对于兄弟组件之间的传值,系统的一些全局状态控制都有很大的帮助。本文通过参考官方文档以及通过demo对Vuex的使用,对Vuex大部分的内容进行了介绍。简单运用的话很快就能上手,但如果想要更熟练的运用,以及把Vuex设计的与整个工程更加匹配,需要更深入的学习,以及更多的开发经验。
最后更新于
这有帮助吗?