vuex
Vue.use(vuex)
const store = new Vuex.Store({
state: {},
getter: {},
action:{},
mutations:{}
})
store.commit()
Vuex 通过store选项,从根组件里注入到每一个子组件里,因此不需要在每个子组件里频繁调用store,子组件通过this.$store 访问到store
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
调用mapstate辅助函数
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
这样我们就可以在子组件里直接使用这些状态了,不是说所有的状态都要存放在Vuex的state里面,有些局部组件可以保留自身的状态
getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
getters里的函数接受state作为其第一个参数
Getter 会暴露为store.getters 对象
可以在任何组件中使用getters里的属性
computed: {
x() {
return this.$store.getters.doneTodosCount
}
}
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
不能直接调用mutation.handler 方法,需要使用 store.commit 来触发唤醒mutation.handler
store.commit('increment')
提交载荷Payload
向store.commit传入额外的参数,即mutation的载荷(payload)
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
一般payload 应该是一个对象,这样属性更加易读
规则
既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
-
最好提前在你的 store 中初始化好所有所需属性。
-
当需要在对象上添加新属性时,你应该
-
使用
Vue.set(obj, 'newProp', 123)
, 或者 -
以新对象替换老对象。例如,利用 stage-3 的对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }
mutation必须是同步函数
在组件中提交 Mutation
你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
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
action 不同的地方在于
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:
两种略微不同的调用方法
computed: {
...mapGetters(["isLogin", "user"])
},
computed: mapGetters([
'evenOrOdd'
]),
methods: mapActions([
'increment',
'decrement',
'incrementIfOdd',
'incrementAsync'
])