Vuex4中组件与Store交互方式对比:
- Options API通过mapState/mapGetters/mapMutations/mapActions等辅助函数或this.$store直接访问;
- Composition API则统一使用useStore获取实例,配合computed/watch实现响应式访问。
关键区别在于:
- Options API自动处理响应式,按选项组织代码;
- Composition API需手动包装状态,按功能逻辑组织代码。
Mutation必须同步修改状态,Action可包含异步操作,Getter用于派生计算属性。
Vuex4专为Vue3设计,提供完整TypeScript支持,模块系统通过命名空间管理状态隔离。
两种API风格都能有效实现状态管理,开发者可根据项目需求选择适合的方式。
Vuex是Vue.js的状态管理库,提供集中式存储和可预测的状态变更。
Pinia已成为Vue官方推荐的新状态管理库,兼容Vue2.x,API与Vuex5类似。
Vuex3/4将继续维护但不添加新功能。
两者可共存,但新项目建议使用Pinia。
Vuex的核心流程包括:组件通过dispatch触发actions异步操作,actions通过commit调用mutations同步修改state,最终state变化触发视图更新。
Vuex 4 中视图(组件)与 Store 交互 - Options API
| 交互场景 | 对应 API | 使用方式 | 适用场景 | 特点 |
|---|---|---|---|---|
| 获取状态 | mapState |
1. 数组形式:mapState(['count', 'user']) 2. 对象形式:mapState({ localCount: 'count' }) 3. 函数形式:mapState({ sum: state => state.a + state.b }) |
组件需要访问 store 中的状态 | - 将 store 状态映射为组件的计算属性 - 自动响应状态变化 - Options API 专用辅助函数 |
| 获取派生状态 | mapGetters |
1. 数组形式:mapGetters(['doneTodos']) 2. 对象形式:mapGetters({ doneCount: 'doneTodosCount' }) |
组件需要访问计算后的状态 | - 映射为组件的计算属性 - 复用复杂状态逻辑 - Options API 专用辅助函数 |
| 提交变更 | mapMutations |
1. 数组形式:mapMutations(['increment']) 2. 对象形式:mapMutations({ add: 'increment' }) |
组件需要提交 mutation 同步修改状态 | - 映射为组件方法 - 只能同步操作 - Options API 专用辅助函数 |
| 分发动作 | mapActions |
1. 数组形式:mapActions(['fetchUser']) 2. 对象形式:mapActions({ getUser: 'fetchUser' }) |
组件需要触发异步操作或复杂业务逻辑 | - 映射为组件方法 - 可包含异步操作 - Options API 专用辅助函数 |
| 模块交互 | 命名空间辅助函数 | createNamespacedHelpers('moduleName') const { mapState } = createNamespacedHelpers('user') |
访问特定命名空间模块的状态/方法 | - 简化命名空间模块的访问 - 避免名称冲突 - Options API 专用 |
| 直接访问 | this.$store |
this.$store.state.count this.$store.commit('increment') this.$store.dispatch('fetchUser') |
在组件方法中直接操作 store | - 不需要辅助函数映射 - 适合在组件方法内部使用 |
| 模块交互 | 命名空间路径 | this.$store.state.moduleA.data this.$store.getters['moduleA/getterName'] this.$store.commit('moduleA/mutationName') |
直接访问模块内的内容 | - 需要知道完整路径 - 适合简单访问 - Options API 中通过 this.$store 访问 |
Vuex 4 中视图(组件)与 Store 交互 - Composition API
| 交互场景 | 对应 API | 使用方式 | 适用场景 | 特点 |
|---|---|---|---|---|
| 获取 store 实例 | useStore |
import { useStore } from 'vuex' const store = useStore() |
获取 Vuex store 实例 | - Composition API 的入口点 - 必须在 setup() 函数内调用 |
| 获取状态 | store.state + computed |
const count = computed(() => store.state.count) const user = computed(() => store.state.user) |
访问 store 中的状态 | - 结合 Vue 3 的 computed 函数 - 自动响应式更新 |
| 获取派生状态 | store.getters + computed |
const doneTodos = computed(() => store.getters.doneTodos) const filteredList = computed(() => store.getters['module/filtered']) |
访问计算后的状态 | - 直接访问 getters 对象 - 支持命名空间路径 |
| 提交变更 | store.commit |
1. 字符串风格:store.commit('increment', payload) 2. 对象风格:store.commit({ type: 'increment', ...payload }) 3. 命名空间:store.commit('module/increment', payload) |
提交 mutation 同步修改状态 | - 直接调用 store 实例方法 - 支持所有 mutation 调用方式 |
| 分发动作 | store.dispatch |
1. 字符串风格:store.dispatch('fetchUser', payload) 2. 对象风格:store.dispatch({ type: 'fetchUser', ...payload }) 3. 命名空间:store.dispatch('module/fetchUser', payload) |
触发异步操作或复杂业务逻辑 | - 直接调用 store 实例方法 - 支持所有 action 调用方式 |
| 响应状态变化 | watch + store.state |
watch(() => store.state.user, (newVal) => {...}) watch(() => store.state.module.data, handler) |
监听 store 中特定状态的变化 | - 精细控制监听逻辑 - 可执行副作用操作 - Composition API 风格 |
| 响应状态变化 | watchEffect |
watchEffect(() => { console.log(store.state.count) }) |
自动追踪依赖的状态变化 | - 自动收集依赖 - 立即执行一次 |
| 模块交互 | 直接路径访问 | store.state.moduleA.data store.getters['moduleA/getterName'] store.commit('moduleA/mutationName') store.dispatch('moduleA/actionName') |
直接访问模块内的内容 | - 需要知道完整路径 - 统一通过 store 实例访问 |
| 创建响应式引用 | toRefs + store.state |
import { toRefs } from 'vue' const { count, user } = toRefs(store.state) |
将状态解构为响应式引用 | - 保持响应式的同时解构状态 - 避免 .value 访问 |
代码示例对比
Options API 示例
javascript
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
computed: {
// 映射状态
...mapState(['count', 'user']),
...mapState({
localCount: 'count'
}),
// 映射 getters
...mapGetters(['doubleCount'])
},
methods: {
// 映射 mutations
...mapMutations(['increment']),
// 映射 actions
...mapActions(['fetchUser']),
// 直接通过 $store 访问
customMethod() {
this.$store.commit('increment')
this.$store.dispatch('fetchUser')
}
}
}
Composition API 示例
javascript
import { useStore } from 'vuex'
import { computed, watch } from 'vue'
export default {
setup() {
const store = useStore()
// 状态访问
const count = computed(() => store.state.count)
const user = computed(() => store.state.user)
// getters 访问
const doubleCount = computed(() => store.getters.doubleCount)
// 方法封装
const increment = () => store.commit('increment')
const fetchUser = () => store.dispatch('fetchUser')
// 监听状态变化
watch(
() => store.state.count,
(newCount) => {
console.log('Count changed:', newCount)
}
)
// 模块访问示例
const moduleData = computed(() => store.state.moduleA.data)
const updateModuleData = () => store.commit('moduleA/update', payload)
return {
count,
user,
doubleCount,
increment,
fetchUser,
moduleData,
updateModuleData
}
}
}
关键差异总结
-
访问方式
-
Options API: 主要通过辅助函数 (
mapXxx) 或this.$store -
Composition API: 统一通过
useStore()返回的 store 实例
-
-
响应式处理
-
Options API: 辅助函数自动处理响应式
-
Composition API: 需要手动使用
computed()包装状态
-
-
模块访问
-
Options API: 可以使用
createNamespacedHelpers或完整路径 -
Composition API: 统一使用完整路径访问
-
-
代码组织
-
Options API: 按选项 (computed, methods) 组织
-
Composition API: 按功能逻辑组织,相关代码集中在一起
-
重要注意事项
-
Mutation: 必须是同步函数,用于状态变更
-
Action: 可以包含异步操作,通过提交 mutation 来改变状态
-
Getter: 类似于计算属性,会对结果进行缓存
-
响应式: Vuex 4 与 Vue 3 响应式系统完全集成,状态变化会自动更新组件
Vuex 4 专门为 Vue 3 设计,提供了完整的 TypeScript 支持,在 Composition API 中尤其强大。
Vuex 4 Store 内部数据流转和 API 总结
1. 核心概念数据流转
| 数据流转方向 | 触发方式 | 使用 API | 执行内容 | 是否可异步 | 开发者控制 | 典型场景 |
|---|---|---|---|---|---|---|
| 组件 → Action | 用户交互、组件生命周期 | dispatch() |
处理业务逻辑、异步操作、组合多个 mutations | 是 | 直接调用 | API 请求、复杂业务逻辑、条件判断 |
| Action → Mutation | Action 内部逻辑 | commit() |
提交状态变更请求,传递载荷(payload) | 否 | 间接调用 | 准备数据、验证后提交变更 |
| Mutation → State | Mutation 执行 | 直接赋值 | 实际修改状态数据 | 否 | 间接控制 | 状态更新、数组操作、对象修改 |
| State → Getter | 状态读取时自动计算 | getter 函数 | 基于状态派生新数据,类似计算属性 | 否 | 定义函数 | 过滤列表、计算统计值、格式化数据 |
| Getter → 组件 | 组件访问状态时 | getters 访问 |
提供派生状态给组件使用 | 否 | 读取结果 | 显示处理后的数据、复用复杂逻辑 |
2. Store 内部 API 详解
| API 类别 | 方法名 | 参数格式 | 返回值 | 作用 | 使用限制 |
|---|---|---|---|---|---|
| 状态管理 | state |
- | 响应式对象 | 存储应用状态 | 只能通过 mutation 修改 |
| 变更提交 | commit(type, payload) |
1. (mutationName, payload) 2. ({ type: mutationName, ...payload }) |
void | 提交 mutation 同步修改状态 | 必须对应已注册的 mutation |
| 动作分发 | dispatch(type, payload) |
1. (actionName, payload) 2. ({ type: actionName, ...payload }) |
Promise | 分发 action 处理异步或复杂逻辑 | 返回 Promise,可链式调用 |
| 计算属性 | getters |
- | 各种类型 | 提供基于 state 的计算值 | 必须有返回值 |
| 模块注册 | registerModule(path, module) |
1. (path, module) 2. (path, module, options) |
void | 动态注册模块 | 已存在的模块不能被重复注册 |
| 模块卸载 | unregisterModule(path) |
(path) |
void | 动态卸载模块 | 不能卸载静态模块 |
| 状态替换 | replaceState(state) |
(state) |
void | 替换整个 store 的状态 | 谨慎使用,可能破坏响应式 |
| 插件监听 | subscribe(callback) |
(callback) |
取消订阅函数 | 监听 mutation 提交 | callback 接收 mutation 和 state |
| 动作监听 | subscribeAction(callback) |
(callback) |
取消订阅函数 | 监听 action 分发 | callback 接收 action 和 state |
| 热重载 | hotUpdate(newOptions) |
(newOptions) |
void | 开发时热更新模块 | 仅用于开发环境 |
3. Mutation 与 Action 对比
| 特性 | Mutation | Action |
|---|---|---|
| 目的 | 修改状态 | 组合业务逻辑 |
| 调用方式 | commit() |
dispatch() |
| 异步性 | 必须同步 | 可以异步 |
| 返回值 | 无 | 可返回 Promise |
| 可追踪性 | 被 Devtools 记录 | 可被 subscribeAction 监听 |
| 执行顺序 | 同步立即执行 | 可包含异步操作 |
| 典型用途 | 直接状态变更 | API 调用、条件逻辑、多个 mutation 组合 |
| 调试 | 有状态快照 | 有 before/after 钩子 |
4. 模块内部 API 结构
| API 类型 | 模块中定义位置 | 访问方式 | 命名空间影响 | 示例 |
|---|---|---|---|---|
| state | 模块选项 | store.state.moduleName |
状态自动命名空间化 | state: { count: 0 } |
| getters | getters 对象 |
store.getters['moduleName/getterName'] |
自动添加命名空间前缀 | doubleCount(state) { return state.count * 2 } |
| mutations | mutations 对象 |
store.commit('moduleName/mutationName') |
自动添加命名空间前缀 | increment(state) { state.count++ } |
| actions | actions 对象 |
store.dispatch('moduleName/actionName') |
自动添加命名空间前缀 | async fetchData({ commit }) { ... } |
| 嵌套模块 | modules 对象 |
多级路径访问 | 路径继承父级命名空间 | modules: { subModule: { ... } } |
| 本地上下文 | Action 参数 | { state, commit, dispatch, getters, rootState, rootGetters } |
自动提供本地和根上下文 | actionName(context) { ... } |
5. 数据流转示例流程
javascript
组件触发
↓
dispatch('fetchUser', userId) // 组件调用
↓
Action: fetchUser(context, payload)
│ → 发起 API 请求 (异步)
│ → 处理响应数据
↓
commit('SET_USER', userData) // Action 内部调用
↓
Mutation: SET_USER(state, payload)
│ → 直接修改 state.user
↓
State 更新 (user 数据变化)
↓
Getter: currentUser(state) 自动重新计算
│ → 基于新 state.user 派生数据
↓
组件自动重新渲染
│ → computed 属性获取新值
↓
视图更新完成
6. 插件和辅助 API
| API | 用途 | 使用时机 | 示例 |
|---|---|---|---|
createStore(options) |
创建 store 实例 | 应用初始化 | const store = createStore({ state, mutations, actions }) |
createLogger(options) |
创建日志插件 | 开发环境调试 | plugins: [createLogger()] |
store.subscribe() |
监听 mutations | 日志、持久化 | store.subscribe((mutation, state) => { console.log(mutation.type) }) |
store.subscribeAction() |
监听 actions | 性能监控、错误追踪 | store.subscribeAction({ before: (action) => {...}, after: (action) => {...} }) |
store.watch() |
响应式监听状态 | 特定状态变化处理 | store.watch(state => state.user, user => { ... }) |
7. 类型安全的 TypeScript 支持
| API | TypeScript 类型 | 用途 | 示例 |
|---|---|---|---|
State 类型 |
interface StoreState |
定义状态结构 | interface State { user: User; count: number } |
Getter 类型 |
函数类型 | 定义 getter 类型 | getters: { doubleCount: (state: State) => number } |
Mutation 类型 |
函数类型 | 定义 mutation 类型 | mutations: { [MutationTypes.SET_USER]: (state: State, user: User) => void } |
Action 类型 |
函数类型 | 定义 action 类型 | actions: { [ActionTypes.FETCH_USER]: (context: ActionContext, id: string) => Promise<void> } |
Store 泛型 |
Store<State> |
类型化 store 实例 | const store: Store<State> = createStore({ ... }) |