Vue状态(视图共享)管理:Vuex
设想一下,如果不用Vuex,我们应该如何在页面各组件之间传值?通过props、$emit在父子组件之间来回穿梭传值?抑或通过bus在组件之间共享值?无论哪种方式,都是极其麻烦或者可读性非常差的。而Vuex的引入很好的解决了这个问题,它把一些共享的属性(状态)集中的管理起来,使得你只需要关注Vuex中定义的state就可以了,state的变化会自动响应到引用了它的视图(页面组件),Vuex很好的解决了以下两个问题:
1、多个视图依赖于同一状态。
2、来自不同视图的行为需要变更同一状态。
一个简单的Vuex的示例如下:
1
|
import Vue from 'vue'
|
1、Vuex的核心
Vuex的核心部分包括:State、Getter、Mutation、Action、Module
- State:vuex中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state访问到它。
- Getter:Getter相当于vue中的computed计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
- Mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。提交mutation必须是同步的方式(不可以异步)。
- Action:Action 类似于 mutation,不同在于:
a、Action 提交的是 mutation,而不是直接变更状态。
b、Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。Action 通过 store.dispatch 方法触发,如:1
store.dispatch('increment')
Action不受同步的约束!我们可以在 action 内部执行异步操作:
1
|
actions: {
|
注:建议最好所有的Mutation操作都用action分发,这样如果业务发生变更(需要由同步变成异步的操作方式),你只需要更改store中的相关action定义就可以了,而不需要去修改引用它的业务代码。
- Module:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。分模块后更便于维护store,如果所有状态都放在一个store中会使得这个store过于臃肿,且不易于维护。
2、在视图(页面组件)中访问State、Getter、Mutation、Action
在页面视图中,我们可以分别使用this.$store.state、this.$store.getters访问State和Getter,使用this.$store.commit(‘xxx’) 提交 mutation,使用this.$store.dispatch(‘xxx’) 分发 action。但这样使用并不规范也不方便,vuex提供了相应的辅助函数:mapState、mapGetters、mapMutations、mapActions用来分别访问它们。示例如下:
1
|
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
|
3、示例demo
一个简单的Vuex的示例Demo,请访问https://github.com/johnnynie/vue-demos/tree/master/vuex-demos/demo1