Vuex 是 Vue.js 官方的状态管理模式,专为 Vue.js 应用程序开发。
状态管理是指在一个应用中,对多个组件共享的数据进行统一管理的方式。在 Vue 应用中,我们可以将状态分为以下几类:
data 选项定义组件内部状态 → 父子组件通信(props/emit) → 事件总线(Event Bus) → Vuex当应用变得复杂时,会遇到以下问题:
// 父子组件通信 - 适合简单的父子关系
this.$emit("update-data", newData)
// 事件总线 - 适合简单跨组件通信,但难以追踪
EventBus.$emit("event-name", data)
EventBus.$on("event-name", handler)
// 全局变量 - 无响应式,难以维护
window.globalData = { user: null }| 特性 | 说明 |
|---|---|
| 集中式存储 | 所有状态集中管理,便于维护和调试 |
| 响应式 | 状态变化自动更新视图 |
| 可预测 | 通过 Mutation 追踪状态变化 |
| 调试工具 | 配合 Vue Devtools 进行时间旅行调试 |
| 模块化 | 支持模块分割,适合大型应用 |
Vuex 采用单向数据流的设计理念:
| 概念 | 作用 | 特点 |
|---|---|---|
| State | 存储应用状态 | 响应式,组件通过计算属性获取 |
| Getter | 派生状态 | 类似计算属性,有缓存 |
| Mutation | 同步修改状态 | 唯一修改状态的途径 |
| Action | 异步操作 | 提交 Mutation,不直接修改状态 |
| Module | 模块分割 | 将 store 分割成模块 |
# npm
npm install vuex@3 --save
# yarn
yarn add vuex@3注意:Vue 2 需要使用 Vuex 3.x 版本
// store/index.js
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0,
user: null
},
mutations: {
increment(state) {
state.count++
},
setUser(state, user) {
state.user = user
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit("increment")
}, 1000)
}
},
getters: {
doubleCount: (state) => state.count * 2,
isLoggedIn: (state) => !!state.user
}
})
export default store// main.js
import Vue from "vue"
import App from "./App.vue"
import store from "./store"
new Vue({
store,
render: (h) => h(App)
}).$mount("#app")<template>
<div>
<p>Count: {{ count }}</p>
<p>Double: {{ doubleCount }}</p>
<button @click="increment">+1</button>
<button @click="incrementAsync">异步+1</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from "vuex"
export default {
computed: {
...mapState(["count"]),
...mapGetters(["doubleCount"])
},
methods: {
...mapMutations(["increment"]),
...mapActions(["incrementAsync"])
}
}
</script>| 对比项 | 全局变量 | Vuex |
|---|---|---|
| 响应式 | ❌ 无 | ✅ 有 |
| 状态追踪 | ❌ 无法追踪 | ✅ 可追踪每次变化 |
| 调试支持 | ❌ 无 | ✅ Vue Devtools 支持 |
| 时间旅行 | ❌ 不支持 | ✅ 支持状态快照 |
| 模块化 | ❌ 难以组织 | ✅ 原生支持模块 |
| 热重载 | ❌ 不支持 | ✅ 支持模块热重载 |
| 类型安全 | ❌ 无 | ✅ 可配合 TypeScript |
// 全局变量 - 无响应式
window.globalState = { count: 0 }
window.globalState.count = 1 // 视图不会更新
// Vuex - 响应式
store.state.count = 1 // 视图自动更新提示:对于小型应用,可以考虑使用简单的状态管理模式或组合式 API 中的响应式 API(Vue 2.7 已内置,低版本可用
@vue/composition-api插件)。
| Vue 版本 | Vuex 版本 |
|---|---|
| Vue 2.x | Vuex 3.x |
| Vue 3.x | Vuex 4.x |