什么是 Vuex?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
为什么需要 Vuex?
在 Vue.js 应用程序中,组件之间的数据传递和状态管理可能变得非常复杂,尤其是在大型应用程序中。在这些情况下,Vuex 可以成为一种简化状态管理
的有力工具。
Vuex 可以使得应用程序的数据流更加清晰和易于维护,同时还可以使得数据流的追踪更加容易。
核心概念
State
Vuex 中的 state 表示应用程序中的所有状态。它可以看作是一个单一的源,即数据的唯一来源
。Vuex 中的 state 是响应式的
,当它发生变化时,所有依赖它的组件都会重新渲染
。
定义一个状态:
const store = new Vuex.Store({
state: {
count: 0
}
})
在组件中读取状态:
// 从 store 中读取 count 状态
computed: {
count () {
return this.$store.state.count
}
}
Getter
Getter 是 Vuex 中的计算属性
,用于从 state 中派生出一些新的状态。Getter 可以接受其他 Getter 作为参数,从而允许我们在一个 Getter 中定义另一个 Getter。
定义一个 getter:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '学习 Vue.js', done: true },
{ id: 2, text: '学习 Vuex', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
在组件中读取 getter:
// 从 store 中读取 doneTodos getter
computed: {
doneTodos () {
return this.$store.getters.doneTodos
}
}
Mutation
Mutation(变更):是更改 Vuex 中状态的唯一推荐方式
,它类似于事件,每个 mutation 都有一个字符串类型的事件类型和一个回调函数,该回调函数就是实际进行状态更改的地方。在 mutation 中,我们可以直接更改状态,并且 Vuex 会跟踪状态的变化,从而可以在 Vue 组件中使用这些变化。需要注意的是,mutation 必须是同步函数
。
定义一个 mutation:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
// 在组件中使用
this.$store.commit('increment')
在上面的代码中,我们创建了一个 Vuex store,并定义了一个 state 对象来存储应用程序状态。同时我们还定义了一个 mutations 对象来存储用于更改状态的方法。在 mutations 对象中,我们定义了一个名为 increment 的方法,它的作用是将状态中的 count 属性自增 1。在组件中,我们可以使用 $store.commit 方法来提交一个 mutation,从而触发状态的更新。
需要注意的是,mutation 必须是同步函数
,因为它们用于更改状态,如果我们使用异步函数,那么就无法保证状态更新的顺序和一致性。
Action
Action 类似于 Mutation,但是可以进行异步操作
。Action 的回调函数接受一个 context 参数
,它与 store 实例具有相同的方法和属性,因此我们可以使用 context.commit() 触发 Mutation,并通过 context.state 和 context.getters 访问 state 和 Getter。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
// 在组件中使用
this.$store.dispatch('incrementAsync')
在上面的代码中,我们创建了一个名为 incrementAsync 的 action,并在参数中接收context中的commmit。它的作用是延迟 1 秒钟,然后调用 commit 方法触发 increment mutation 来更新状态。在组件中,我们可以使用 $store.dispatch 方法来触发一个 action,从而异步地更改状态。
需要注意的是,action 可以返回一个 Promise,从而使调用者可以等待异步操作完成。这使得我们可以在异步操作完成后执行一些额外的操作。
Module
Module 是 Vuex 中的一种组织方式,允许将 store 分割成多个模块。每个 Module 都具有自己的 state、getter、mutation、action。
const moduleA = {
state: {
countA: 0
},
mutations: {
incrementA(state) {
state.countA++
}
},
actions: {
incrementAAsync({ commit }) {
setTimeout(() => {
commit('incrementA')
}, 1000)
}
},
getters: {
doubleCountA(state) {
return state.countA * 2
}
}
}
const moduleB = {
state: {
countB: 0
},
mutations: {
incrementB(state) {
state.countB++
}
},
actions: {
incrementBAsync({ commit }) {
setTimeout(() => {
commit('incrementB')
}, 1000)
}
},
getters: {
doubleCountB(state) {
return state.countB * 2
}
}
}
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
// 在组件中使用
this.$store.state.moduleA.countA // 获取 moduleA 中的 countA 状态
this.$store.commit('moduleA/incrementA') // 触发 moduleA 中的 incrementA mutation
this.$store.dispatch('moduleA/incrementAAsync') // 触发 moduleA 中的 incrementAAsync action