一、Vuex 核心概念与适用场景
Vuex 是专为 Vue.js 设计的集中式状态管理模式,用于解决组件间状态共享问题。其核心适用场景包括:
- 多组件共享状态(如用户登录信息、全局配置)
- 组件间复杂通信(如跨层级组件传值)
- 状态的持久化与统一维护
二、Vuex 五大核心模块
| 模块 | 作用 | 示例 |
|---|---|---|
| state | 存储应用状态(单一数据源) | state: { count: 0 } |
| getters | 计算属性,派生状态(类似 Vue 的 computed) | getters: { doubleCount: state => state.count * 2 } |
| mutations | 唯一允许修改 state 的地方(同步操作) | mutations: { increment(state) { state.count++ } } |
| actions | 处理异步操作(如 API 请求),提交 mutations | actions: { async incrementAsync({ commit }) { await api.call(); commit('increment') } } |
| modules | 将 store 分割为多个模块(适用于大型应用) | modules: { user: { state: { name: 'John' } } } |
三、基础使用流程
-
定义 Store
javascript
import { createStore } from 'vuex'; const store = createStore({ state() { return { count: 0, user: null }; }, mutations: { increment(state) { state.count++; }, setUser(state, payload) { state.user = payload; } }, actions: { login({ commit }, credentials) { return api.login(credentials).then(user => { commit('setUser', user); }); } }, getters: { isLoggedIn(state) { return state.user !== null; } } }); export default store; -
在组件中使用
vue
<template> <div> <p>Count: {{ count }}</p> <button @click="increment">+</button> <button @click="login">Login</button> </div> </template> <script> import { mapState, mapMutations, mapActions } from 'vuex'; export default { computed: { ...mapState(['count']), ...mapState({ isLoggedIn: state => state.user !== null }) }, methods: { ...mapMutations(['increment']), ...mapActions(['login']) } }; </script>
四、进阶特性
-
模块化(Modules)
javascript
// store/modules/user.js export default { namespaced: true, // 启用命名空间 state: { name: '' }, mutations: { /* ... */ }, actions: { /* ... */ }, getters: { /* ... */ } }; // 在根 store 中注册 const store = createStore({ modules: { user: userModule } }); -
插件(Plugins)
用于记录状态变更(如日志、持久化):javascript
const myPlugin = store => { store.subscribe((mutation, state) => { console.log(`Mutation: ${mutation.type}`, mutation.payload); }); }; const store = createStore({ plugins: [myPlugin] }); -
严格模式(Strict Mode)
强制所有 state 修改通过 mutations(仅开发环境使用):javascript
const store = createStore({ strict: process.env.NODE_ENV !== 'production' });
五、与组件通信的对比
| 场景 | Vuex | 组件通信 |
|---|---|---|
| 跨层级状态共享 | ✅ 全局唯一数据源 | ❌ 多层级传递复杂 |
| 状态持久化 | ✅ 配合插件实现 | ❌ 需要额外实现 |
| 复杂异步操作 | ✅ 集中处理(actions) | ❌ 分散在组件中管理困难 |
| 简单父子 / 兄弟组件通信 | ❌ 杀鸡用牛刀 | ✅ props/$emit 更简洁 |
六、常见问题与最佳实践
-
避免在 mutations 中使用异步操作
- 必须通过 actions 处理异步,否则 devtools 无法正确追踪状态变更。
-
大型应用的状态组织
- 按模块拆分 store(如
user.js、products.js),使用命名空间隔离。
- 按模块拆分 store(如
-
性能优化
- 避免频繁触发大量 mutations,可批量提交。
- 使用
mapState/mapGetters时,通过计算属性缓存结果。
-
状态持久化
- 使用
vuex-persistedstate插件将 state 存储到 localStorage 或 sessionStorage。
- 使用
七、Vue 3 中的使用差异
-
组合式 API 集成
javascript
import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = computed(() => store.state.count); const increment = () => store.commit('increment'); return { count, increment }; } }; -
TypeScript 支持
typescript
import { createStore, Store } from 'vuex'; interface State { count: number; } const store: Store<State> = createStore({ state: { count: 0 } });
八、面试高频问题
-
Vuex 与 localStorage 的区别?
- Vuex:内存中的响应式状态,页面刷新丢失;
- localStorage:持久化存储,但非响应式。
-
为什么 mutations 必须是同步的?
- 为保证 devtools 能正确追踪状态变更的时间旅行调试功能。
-
如何在组件中优雅地使用 Vuex?
- 小型项目:直接使用
mapState/mapActions; - 大型项目:封装业务逻辑到 composables(如
useUserStore)。
- 小型项目:直接使用
-
Vuex vs Pinia
- Pinia 是 Vuex 5 的替代方案,API 更简洁,支持 TypeScript,推荐新项目使用。
总结
Vuex 通过集中式状态管理解决了复杂应用的状态共享问题,核心是理解其单向数据流(view → action → mutation → state → view)的设计思想。合理使用模块化、插件和严格模式,能有效提升代码可维护性和开发效率。
4365

被折叠的 条评论
为什么被折叠?



