一、前言
Vuex 是 Vue 官方推荐的状态管理模式,适用于中大型 Vue 应用程序的全局状态管理。它通过集中式的 Store 管理组件之间的共享数据,使得状态变更更加可预测和易于维护。
本文将带你深入了解 Vuex 的五大核心概念(State、Getter、Mutation、Action、Module)以及常用的 API 方法,帮助你从基础到进阶掌握 Vuex 的使用方式。
二、Vuex 的五大核心概念
Vuex 主要由五个核心部分组成:
模块 | 类型 | 描述 |
---|---|---|
State | 数据源 | 存储应用的状态数据 |
Getter | 计算属性 | 对 state 进行派生计算 |
Mutation | 同步方法 | 唯一能修改 state 的方式 |
Action | 异步方法 | 提交 mutation,处理异步操作 |
Module | 分割模块 | 将 store 拆分为多个模块,便于组织 |
1. State:存储状态数据
state
是 Vuex 中最基础的数据仓库,用于保存应用程序中的共享状态。
state: {
count: 0,
user: null,
todos: []
}
📌 使用方式:
- 组件中通过
this.$store.state.count
获取; - 推荐结合
mapState
辅助函数简化写法。
import { mapState } from 'vuex'
computed: {
...mapState(['count'])
}
2. Getter:派生状态(类似 computed)
getter
用于对 state 进行加工处理,类似于 Vue 的 computed 属性。
getters: {
doubleCount(state) {
return state.count * 2
},
doneTodos(state) {
return state.todos.filter(todo => todo.done)
}
}
📌 使用方式:
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['doubleCount', 'doneTodos'])
}
3. Mutation:同步更改状态的方法
mutation
是唯一允许修改 state
的地方,必须是同步函数。
mutations: {
increment(state) {
state.count++
},
setUser(state, user) {
state.user = user
}
}
📌 使用方式:
this.$store.commit('increment')
或使用 mapMutations
:
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['increment', 'setUser'])
}
4. Action:异步操作状态的方法
action
用于处理异步逻辑,如请求接口、定时器等,最终通过提交 mutation 来改变状态。
actions: {
async fetchUser({ commit }, userId) {
const res = await getUserById(userId)
commit('setUser', res.data)
},
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
📌 使用方式:
this.$store.dispatch('fetchUser', 1)
或使用 mapActions
:
import { mapActions } from 'vuex'
methods: {
...mapActions(['fetchUser', 'incrementAsync'])
}
5. Module:模块化组织 Store
当项目变大时,我们可以将 store 拆分成多个模块(module),每个模块拥有自己的 state、getter、mutation 和 action。
modules: {
userModule,
cartModule
}
模块示例:
// modules/userModule.js
export default {
namespaced: true,
state: () => ({
userInfo: null
}),
mutations: {
setUserInfo(state, info) {
state.userInfo = info
}
},
actions: {
fetchUserInfo({ commit }) {
// ...
commit('setUserInfo', data)
}
}
}
📌 使用带命名空间的模块:
dispatch('userModule/fetchUserInfo', null, { root: true })
commit('userModule/setUserInfo', info, { root: true })
三、Vuex 的常用 API 方法汇总
API 名称 | 描述 |
---|---|
$store.state.xxx | 获取状态值 |
$store.getters.xxx | 获取计算后的状态值 |
$store.commit('type', payload) | 触发 mutation |
$store.dispatch('type', payload) | 触发 action |
$store.registerModule(path, module) | 动态注册模块 |
$store.unregisterModule(path) | 动态卸载模块 |
mapState , mapGetters , mapMutations , mapActions | 辅助函数,简化写法 |
四、辅助函数(mapXXX)详解
为了减少重复代码,Vuex 提供了四个常用的辅助函数,它们都位于 vuex
包中。
1. mapState
将 store 的 state 映射为计算属性。
import { mapState } from 'vuex'
computed: {
...mapState(['count', 'user'])
}
等价于:
computed: {
count() {
return this.$store.state.count
},
user() {
return this.$store.state.user
}
}
2. mapGetters
将 store 的 getter 映射为计算属性。
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['doubleCount', 'doneTodos'])
}
3. mapMutations
将 store 的 mutation 映射为 methods。
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['increment', 'setUser'])
}
4. mapActions
将 store 的 action 映射为 methods。
import { mapActions } from 'vuex'
methods: {
...mapActions(['fetchUser', 'incrementAsync'])
}
五、动态模块注册与卸载
在某些场景下,我们需要在运行时动态添加或移除模块。
✅ 注册模块
store.registerModule('userModule', userModule)
✅ 卸载模块
store.unregisterModule('userModule')
📌 注意:注册后可以通过 root: true
调用模块中的方法。
六、Vuex 在 Vue 2 与 Vue 3 中的区别
特性 | Vue 2(Vuex 3) | Vue 3(Vuex 4) |
---|---|---|
创建 Store 方式 | new Vuex.Store({}) | createStore({}) |
使用方式 | Vue.use(Vuex) | app.use(store) |
Composition API 支持 | 需配合 useStore | 原生支持组合式 API |
TypeScript 支持 | 支持 | 更好地支持 |
推荐程度 | ✅ 旧项目可用 | ✅ 新项目推荐使用 |
七、Vuex 最佳实践建议
建议 | 说明 |
---|---|
不直接修改 state | 必须通过 mutation 修改 |
Mutation 必须同步 | Action 才能执行异步逻辑 |
合理拆分模块 | 避免 store 太臃肿 |
使用命名空间 | 模块化时启用 namespace 提高可维护性 |
封装 map 辅助函数 | 提高代码简洁性和可读性 |
配合 Vue Devtools | 查看状态变化、调试更高效 |
不滥用 Vuex | 小型项目可考虑使用 reactive / ref 替代 |
八、总结对比表
概念 | 是否同步 | 是否可直接修改 state | 是否推荐使用 |
---|---|---|---|
State | ❌ | ❌ | ✅ |
Getter | ✅ | ❌ | ✅ |
Mutation | ✅ | ✅(唯一方式) | ✅ |
Action | ✅(内部异步) | ❌(通过提交 mutation 修改) | ✅ |
Module | ✅ | ✅ | ✅(大项目必备) |
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!