Vuex
主要就是一个状态管理的工具,其核心就是一个store(仓库)这个仓库中有很多的状态(state)
Vuex的相比较于全局对象的特点:
- Vuex的状态存储是响应式的。当vue组件访问store读取状态时,如果store的状态发生变化,相应的组件也会相应的发生变化
- 不可以直接修改store中的状态。如果要改,需通过提交(commit)mutation。这样就可以跟踪每一个状态的变化
创建一个store
import {createApp} from 'vue'
import {createStore} from 'vuex'
//创建store实例
const store = createStore({
state(){
return {
count:0
}
},
mutations:{
increment(state){
state.count++
}
}
})
const app = createApp({/*根组件*/})
app.use(store)
通过store.commit来触发mutation状态更新, 在vue组件中可以通过this.$store.commit触发
store.commit('increment')
//vue组件
methods:{
increment(){
this.$store.commit(increment)
}
}
注意:这是通过commit触发mutation来修改状态的
State
-
vuex使用单一状态树,一个对象就可以包含所有的状态。
-
如何在vue组件中获取vuex状态
由于vuex的状态是响应式的,所以简单的方法就是通过计算属性进行获取并返回
const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } } 当组件中store.state.count发生变化时候,都会重新求取计算属性,并且触发更新相关的DOM在vuex官网中也有一种方法能够帮助我们生成计算属性那就是mapState
Getter
那如何获取到状态呢?Getter就来了
在vuex中允许我们在store中定义getter(在这里我们可以认为是store的计算属性)
而Getter有三种访问状态的方式:
- 通过属性访问
- 通过方法访问
- mapGetters辅助函数访问
具体的例子大家可以参考这里
Mutation
注意我认为重点的来了
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个 回调函数 (handler)
提交载荷(Payload)
可以向store.commit传入第二个参数,也就是mutation的载荷(大多数情况下,载荷应该是一个对象)
重点:Mutation必须是同步函数
在组件中提交Mutation
其实还是上面说的,要通过store.commit来提交Mutation,或者使用mapMutation 辅助函数将组件中的 methods 映射为 store.commit 调用
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。当我们在之后介绍到 Modules 时,你就知道 context 对象为什么不是 store 实例本身了。
分发Action
通过store.dispatch()方法进行分发,有人会想,直接分发mutation不好吗?记得上面的重点吗?
因为 mutation必须是一个同步函数,但是 Action 就不受约束!我们可以在 action 内部执行异步操作
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}