在全局的vue对象注入store,通过this.$store.state访问
new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
template: `
<div class="app">
<counter></counter>
</div>
`
})
State
mapState
state: {...}
computed: {
...mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
// 计算属性的名称与 state 的子节点名称相同时
...mapState([
// 映射 this.count 为 store.state.count
'count'
])
}
Getters
mapGetters
getters: {
// 属性访问
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
},
// 方法访问
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
// 方法访问
this.$store.getters.getTodoById(2)
computed: {
...mapGetters([
'doneTodosCount'
])
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
// 属性访问
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
Mutations
mapMutations
// 整个 app 包含的 mutation 一目了然
export const SOME_MUTATION = 'SOME_MUTATION'
import { SOME_MUTATION } from './mutation-types'
mutations: {
increment (state, payload) {
state.count += payload.amount
},
[SOME_MUTATION] (state) {
// mutate state
}
}
computed: {
...mapMutations(['increment']) // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
this.$store.commit('increment', { amount: 10})
this.$store.commit({
type: 'increment',
amount: 10
})
Actions
mapActions 分发mutation
actions: {
// 接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用context.commit 提交一个 mutation
checkout ({ commit, state }, products) {
// 把当前购物车的物品备份起来
const savedCartItems = [...state.cart.added]
// 发出结账请求,然后乐观地清空购物车
commit(types.CHECKOUT_REQUEST)
// 购物 API 接受一个成功回调和一个失败回调
shop.buyProducts(
products,
// 成功操作
() => commit(types.CHECKOUT_SUCCESS),
// 失败操作
() => commit(types.CHECKOUT_FAILURE, savedCartItems)
)
}
}
this.$store.dispatch('checkout', { amount: 10 })
Modules
// namespaced: true 所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名
// root: true
dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
dispatch('someOtherAction') // -> 'foo/someOtherAction'
foo: {
namespaced: true,
actions: {
someAction: {
root: true,
handler (namespacedContext, payload) { ... } // -> 'someAction'
}
}
}
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
namespaced: true,
state: () => ({ ... }),
getters: {
popular () { ... } // -> store.getters['b/popular']
}
mutations: { ... },
actions: {
incrementIfOddOnRootSum ({ state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
// 简写
...mapActions([
'some/nested/module/foo', // -> this['some/nested/module/foo']()
'some/nested/module/bar' // -> this['some/nested/module/bar']()
])
...mapState('some/nested/module', {
a: state => state.a,
b: state => state.b
})
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')