Vuex4:专为 Vue 3 设计,提供完整 TypeScript 支持

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
    }
  }
}

关键差异总结

  1. 访问方式

    • Options API: 主要通过辅助函数 (mapXxx) 或 this.$store

    • Composition API: 统一通过 useStore() 返回的 store 实例

  2. 响应式处理

    • Options API: 辅助函数自动处理响应式

    • Composition API: 需要手动使用 computed() 包装状态

  3. 模块访问

    • Options API: 可以使用 createNamespacedHelpers 或完整路径

    • Composition API: 统一使用完整路径访问

  4. 代码组织

    • 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({ ... })
相关推荐
无法长大5 小时前
如何判断项目需不需要用、能不能用Tailwind CSS
前端·css·vue.js·elementui·vue3·tailwind css
cui_win1 天前
企业级中后台开源解决方案汇总
开源·vue3·ts
Sapphire~2 天前
Vue3-19 hooks 前端数据和方法的封装
前端·vue3
記億揺晃着的那天2 天前
Vue3 动态路由在生产环境才出现白屏的排查与解决(keep-alive 踩坑实录)
vue3·vue router·动态路由·生产环境报错
kong79069286 天前
Vue3快速入门
前端·vue3
无法长大7 天前
Mac M1 环境下使用 Rust Tauri 将 Vue3 项目打包成 APK 完整指南
android·前端·macos·rust·vue3·tauri·打包apk
淡笑沐白8 天前
Vue3使用ElementPlus实现菜单的无限递归
javascript·vue3·elementplus
Sapphire~8 天前
Vue3-18 生命周期(vue2+vue3)
vue3
Sapphire~9 天前
Vue3-17 父子组件使用props传值
vue3