最近比较闲,抽时间过了一遍vuex的文档。同时写了官网上购物车的那个小demo。下面来总结一下一些vuex的一些知识点vue
官方文档上写:vuex是一个专为vue.js应用程序开发的状态管理模式。这个状态自管理应用包括如下几个部分:vuex
vuex应用的核心就是store(仓库)。"store"基本上就是一个容器,它包含着你的应用中大部分的状态(state)。数组
在vue组件中获取状态异步
// 建立一个 Counter 组件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count } } }
使用mapState辅助函数
在一个组件须要获取多个状态的时候,将这些状态都声明为计算属性会有些复杂。为了解决这个问题,可使用mapState辅助函数模块化
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' export default { computed: mapState({ count: state => state.count, // 传入字符串'count'等同于'state => state.count' countAlias: 'count', // 使用模块而且对应模块名称为cart时,获取cart里面对应的count属性 count: state => state.cart.count }) }
当计算属性的名称与state子节点名称相同时,能够给mapState传入一个字符串数组函数
computed: mapState([ 'count' ])
对象展开运算符...mapStatethis
computed: { localComputed() { ...mapState({ }) } }
从store中的state派生出一些状态。能够理解为store的计算属性。当getter所依赖的值发生改变时,getter的值会随之改变。spa
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
若是你想将一个 getter 属性另取一个名字,使用对象形式:code
mapGetters({ // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount` doneCount: 'doneTodosCount' })
模块化状态下,getter取值对象
// 模块为cart computed: { ...mapGetters('cart', { doneCount: 'doneTodosCount' }) }
更改vuex的store中的状态的惟一办法是提交mutation
注意:
mutation必须是同步函数,异步须要放在aciton中
const store = new Vuex.store({ state: { count:1 }, mutations: { increment (state) { state.count++ } } })
store.commit('increment')
提交载荷(Payload)
你能够向store.commit传入额外的参数,即mutaition的荷载(payload)
mutations: { increment(state, n) { state.count += n } } store.commit('increment', 10)
在组件中提交mutation
import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')` // `mapMutations` 也支持载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')` }) } }
Action相似于mutation。不一样在于:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } // 或者也能够用es2015的解构赋值写成下面这种形式 increment({ commit }) { } } })
分发Action
Action经过store.dispatch方法触发
store.dispatch('increment')
在组件中分发Action
import { mapActions } from 'vuex' export default { // ... methods: { ...mapActions([ 'increment', //将this.increment()映射为this.$store.dispatch('increment') ]) ...mapActions([ add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')` ]) } }
Vuex容许咱们将store分割成模块。
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 的状态
默认状况下,模块内部的action、mutation和getter是注册在全局命名空间的。若是你但愿你的模块具备更高的封装度和复用度,你能够经过添加namespaced:true的方式使其成为带命名空间的模块。在模块被注册后,它全部getter、action及mutation都会自动根据模块注册的路径调整命名。
const store = new Vuex.Store({ modules: { account: { namespaced: true, state: {}, getters: { isAdimin() {...} // getters['account/isAdmin'] } } } })
对于内部模块,若是你但愿获取全局的state和getter,能够经过rootState、rootGetter获取到
若须要在全局命名空间内分发action或者提交mutation,将{root: true}做为第三个参数传给dispatch或者commit便可
// 在另一个模块获取cart模块 rootState.cart.all dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction' commit('someMutation', null, { root: true }) // -> 'someMutation'