vuex知识总结
- Authors
- Name
- 小明&小艺
状态管理
一个状态管理的库,会涉及到这三部分:state、view、actions。可以知道的是:
- state 会影响 view
- view 会影响 action
但会影响 state 的是什么呢?action,action 可能是单一的或者是来自于多个视图的。
vuex 的特点是把数据单独隔离,形成一棵树状图。单独隔离就意味着它有自己的生态系统。输入和输出,其中 action 作为数据的输入,state 作为数据的输出。如下图:
图中有一个奇怪的地方,多了一个 mutations,而且与 state 相连的是 mutations 而不是 actions。
vuex 里有这么一个规则:
只能在 mutaions 里修改 state,actions 不能直接修改 state
mutations 即变化,修改 state 的数据,而且只能是同步的,不能存在异步的操作。如果需要异步怎么办呢?把异步操作放在 actions 里,拿到数据再通过 mutations 同步处理。
vuex 做的其实是把职权明确了,责任细分了。所以它文档里也说,小系统可以不用。状态数据少,没有细分的必要。
使用方法
- Action 通过 store.dispatch 方法触发
- Mutations 通过 store.commit 方法触发
// 触发动作
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
store.dispatch('increment')
// 触发变化
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
为了更方便地读取 state 里面的数据,其还提高了一些维护的方法:
- getters 就像计算属性一样,getters 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
- mapGetters 将 store 中的 getters 映射到局部计算属性
- mapMutations 将组件中的 methods 映射为 store.commit 调用
- mapActions 将组件的 methods 映射为 store.dispatch 调用
methods: {
...mapMutations([
'increment' // 映射 this.increment() 为 this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
})
...mapActions([
'increment' // 映射 this.increment() 为 this.$store.dispatch('increment')
]),
...mapActions({
add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment')
})
}
getter 既然是会缓存的,那怎么带参数呢?github 里有人建议这样写:
getters: {
getListByVal: (state) => (val) => {
return state.list.find(item => item.value = val)
}
}
模块划分
当状态比较多的时候,vuex 支持模块划分,可以通过模块划分,让 store 树简化一下。每个模块拥有自己的 state、mutation、action、getter。
- 对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象
- getter 根节点状态会作为第三个参数暴露出来
- 内部的 action,局部状态通过 context.state 暴露出来, 根节点状态则为 context.rootState
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态