一 核心概念与适用场景
- Vuex 是 Vue.js 的集中式状态管理 库,采用单一状态树 ,以可预测的方式管理应用中多个组件共享的数据。其核心包含五部分:State (状态)、Getters (派生状态)、Mutations (同步修改)、Actions (异步调度)、Modules (模块化)。适用于跨多组件共享数据 、复杂表单 、购物车/登录状态 、路由守卫依赖的全局状态 等场景。数据流遵循:组件触发 Action → Action 执行异步并提交 Mutation → Mutation 同步修改 State → 视图响应更新。
二 环境搭建与项目结构
-
安装(Vue 2 项目):执行命令:
npm install vuex@3 --save(Vuex 3 适配 Vue 2)。 -
目录结构建议:
javascriptsrc/ ├── store/ │ ├── index.js # 创建 store 实例 │ ├── state.js # 全局状态 │ ├── mutations.js # 同步修改 │ ├── actions.js # 异步操作 │ ├── getters.js # 派生数据 │ └── modules/ # 模块化(可选) │ ├── cart.js │ └── user.js └── main.js # 引入并注入 store -
在 main.js 中注册:
javascriptimport Vue from 'vue'; import App from './App.vue'; import store from './store'; // 路径按项目实际调整 new Vue({ store, render: h => h(App) }).$mount('#app'); -
说明:在 Vue 3 项目中应使用 Pinia (官方推荐),如需使用 Vuex 则选择 Vuex 4。
三 核心 API 与使用示例
-
State
-
定义(store/state.js):
javascriptexport default { count: 0, user: { name: 'Guest' } }; -
读取(组件内):
this.$store.state.count。
-
-
Getters
-
定义(store/getters.js):
javascriptexport default { doubleCount: state => state.count * 2, userName: state => state.user.name }; -
读取:
this.$store.getters.doubleCount。
-
-
Mutations(同步修改,唯一途径)
-
定义(store/mutations.js):
javascriptexport default { INCREMENT(state, payload) { state.count += (payload?.step || 1); }, SET_USER(state, user) { state.user = { ...state.user, ...user }; } }; -
提交:
this.$store.commit('INCREMENT', { step: 5 })。
-
-
Actions(异步调度,提交 Mutation)
-
定义(store/actions.js):
javascriptexport default { incrementAsync({ commit }, payload) { return new Promise(resolve => { setTimeout(() => { commit('INCREMENT', payload); resolve(); }, 1000); }); }, async login({ commit }, { username }) { // 模拟 API const user = await fakeApiLogin(username); commit('SET_USER', user); } }; -
派发:
this.$store.dispatch('incrementAsync', { step: 2 })。
-
-
辅助函数(简化模板与代码)
javascriptimport { mapState, mapGetters, mapMutations, mapActions } from 'vuex'; export default { computed: { // 数组写法 ...mapState(['count', 'user']), ...mapGetters(['doubleCount', 'userName']), // 对象写法(可重命名) ...mapState('cart', ['items']) // 模块化时 }, methods: { // 数组写法 ...mapMutations(['INCREMENT']), ...mapActions(['incrementAsync']), // 对象写法(可重命名) ...mapActions('cart', { addToCart: 'ADD_ITEM' }) } }; -
要点:Mutation 必须是同步函数 ;Action 可包含异步 ,并通过
commit改变状态;在组件中优先使用辅助函数 或 Composition API 风格的useStore()(Vuex 3/4 提供)。
四 模块化与命名空间
-
当项目变大,建议按功能拆分模块,避免单一文件臃肿,并开启命名空间以隔离命名冲突与提升可维护性。
-
示例:创建
store/modules/counter.jsjavascriptconst counter = { namespaced: true, // 开启命名空间 state: () => ({ value: 0 }), mutations: { UP(state, n = 1) { state.value += n; } }, actions: { upAsync({ commit }, n) { return new Promise(r => setTimeout(() => commit('UP', n), 300)); } }, getters: { doubled: state => state.value * 2 } }; export default counter; -
在 store/index.js 中注册:
javascriptimport Vue from 'vue'; import Vuex from 'vuex'; import counter from './modules/counter'; Vue.use(Vuex); export default new Vuex.Store({ modules: { counter } }); -
组件内使用(命名空间模块):
javascriptimport { mapState, mapMutations, mapActions, mapGetters } from 'vuex'; export default { computed: { ...mapState('counter', ['value']), ...mapGetters('counter', ['doubled']) }, methods: { ...mapMutations('counter', ['UP']), ...mapActions('counter', ['upAsync']) } }; -
说明:开启命名空间后,访问路径变为
store.state.counter.value、store.getters['counter/doubled']、store.commit('counter/UP')、store.dispatch('counter/upAsync');辅助函数通过第二个参数指定命名空间,或在模板中使用带前缀的路径。
五 实战示例 计数器与异步任务
- 目标:实现一个计数器,支持同步增加 与异步增加 ,并在页面显示双倍值。
- 步骤
-
定义模块(store/modules/counter.js,见上节)。
-
在组件中使用:
javascript<template> <div> <p>Count: {{ value }}</p> <p>Double: {{ doubled }}</p> <button @click="localIncrement">+1</button> <button @click="localIncrementBy(3)">+3</button> <button @click="asyncUp">Async +2</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'; export default { computed: { ...mapState('counter', ['value']), ...mapGetters('counter', ['doubled']) }, methods: { ...mapMutations('counter', ['UP']), ...mapActions('counter', ['upAsync']), localIncrement() { this.UP(); }, localIncrementBy(n) { this.UP({ step: n }); } } }; </script> -
运行与验证:点击按钮观察
count与doubled的变化;异步操作完成后状态同步更新。 -
小贴士:在 严格模式 下,仅允许通过 Mutation 修改状态,有助于捕捉非法直接修改;开发阶段可开启以提升可维护性与可调试性。
-