news 2026/9/19 3:23:51

Vuex 4 迁移指南:从 Vuex 3.x 升级到 4.0 的破坏性变更与新特性实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vuex 4 迁移指南:从 Vuex 3.x 升级到 4.0 的破坏性变更与新特性实战

Vuex 4 迁移指南:从 Vuex 3.x 升级到 4.0 的破坏性变更与新特性实战

【免费下载链接】vuex🗃️ Centralized State Management for Vue.js.项目地址: https://gitcode.com/gh_mirrors/vu/vuex

本篇指南基于 Vuex 官方迁移文档(docs/guide/migrating-to-4-0-from-3-x.md)整理而成,系统梳理从 Vuex 3.x 升级到 Vuex 4(本仓库当前版本为 4.1.0)时必须处理的破坏性变更:安装流程、TypeScript 支持、构建产物形态以及createLogger的导出位置变化,并介绍 Vuex 4 引入的新特性useStore组合式函数。读完本文,你将能够对照迁移清单逐项改造现有 Vuex 3 项目,完成与 Vue 3 生态对齐的升级。

Vuex 4 的核心 API 几乎全部沿袭自 Vuex 3,绝大多数代码无需改动即可继续工作;真正的风险集中在少数破坏性变更上。先给出结论,再逐项展开:

变更类别3.x 写法4.x 写法
创建 storenew Vuex.Store({...})createStore({...})
安装到应用Vue.use(Vuex)app.use(store)
TypeScript 中的this.$store内置全局类型需自行声明模块扩充(module augmentation)
createLogger导入vuex/dist/logger直接从vuex导入
Composition API 取 store无(需手动provide/injectuseStore()

破坏性变更一:安装流程(Installation process)

为了与 Vue 3 全新的初始化流程对齐,Vuex 4 的安装方式发生了改变。Vue 3 应用不再通过Vue.use()全局安装插件,而是先创建应用实例、再通过app.use()安装 store。相应地,Vuex 4 引入createStore函数用于创建 store:

import { createStore } from 'vuex' export const store = createStore({ state () { return { count: 1 } } })

安装时,把store 本身(而不是 Vuex 插件对象)传给app.use()

import { createApp } from 'vue' import { store } from './store' import App from './App.vue' const app = createApp(App) app.use(store) app.mount('#app')

从源码结构看,createStore只是Store构造函数的语法糖:在 src/store.js 中,createStore(options)直接return new Store(options);而Store类在 src/store.js 中实现了install(app, injectKey)方法,其核心工作是:

install (app, injectKey) { app.provide(injectKey || storeKey, this) app.config.globalProperties.$store = this // ...devtools 接入 }

即通过 Vue 3 的 Provide/Inject 机制向整棵组件树提供 store,同时把它挂到app.config.globalProperties.$store,从而保持 Options API 中this.$store的访问方式不变。

提示:严格来说new Store({...})的语法在 Vuex 4 中仍然可用(Store类依旧被导出,见 src/index.js),并不构成破坏性变更。但官方推荐使用createStore,以便与 Vue 3 和 Vue Router Next 的初始化风格保持一致。

破坏性变更二:TypeScript 支持

Vuex 4移除了 Vue 组件内this.$store的全局类型声明,这是为了解决 issue #994(全局类型声明会污染所有组件的this类型推断)。因此,在 TypeScript 项目中必须自己声明模块扩充(module augmentation),为this.$store提供正确的类型。

在项目中添加如下声明文件(例如vuex-shim.d.ts):

// vuex-shim.d.ts import { ComponentCustomProperties } from 'vue' import { Store } from 'vuex' declare module '@vue/runtime-core' { // Declare your own store states. interface State { count: number } interface ComponentCustomProperties { $store: Store<State> } }

这份声明文件需要被 TypeScript 纳入编译范围(通常只要放在项目根目录或被tsconfig.jsoninclude覆盖即可)。更完整的类型化方案——包括使用InjectionKeyuseStore注入类型、以及封装自定义useStore组合函数以避免到处传 key 的样板代码——参见 docs/guide/typescript-support.md,仓库的类型声明位于 types/index.d.ts,并有 types/test/index.ts 等类型测试用例持续校验。

破坏性变更三:构建产物与 Vue 3 对齐(Bundles are now aligned with Vue 3)

Vuex 4 生成的构建产物与 Vue 3 保持完全一致的命名与形态约定,共四类:

构建产物用途特点
vuex.global(.prod).js浏览器<script src="...">直接引入暴露Vuex全局变量;IIFE 格式(不再是 UMD);内置硬编码的 prod/dev 分支,.prod.js为预压缩版本,生产环境必须使用
vuex.esm-browser(.prod).js原生 ES Module 导入供浏览器<script type="module">直接使用
vuex.esm-bundler.js配合webpackrollupparcel等打包器保留process.env.NODE_ENV分支守卫,由打包器在构建时替换;不附带压缩版本(压缩在整体打包后统一进行)
vuex.cjs.jsNode.js 服务端渲染(SSR)通过require()引入的 CommonJS 格式

这六份产物(含 prod 变体)的产出规则定义在 rollup.config.js:vuex.esm-browser.jsvuex.esm-browser.prod.jsformat: 'es'+browser: truevuex.esm-bundler.jsformat: 'es'且不标记 browser;vuex.global(.prod).jsformat: 'iife',其输出名固定为Vuexvuex.cjs.jsformat: 'cjs'。其中__DEV__的替换策略也印证了文档描述(rollup.config.js):bundler 版本替换为(process.env.NODE_ENV !== 'production')表达式,其余版本按构建环境硬编码为布尔值。

在实际项目中,package.json 的入口映射决定了不同环境下使用哪份产物:main指向dist/vuex.cjs.js(Node/CommonJS)、module指向dist/vuex.esm-bundler.js(打包器)、browser指向dist/vuex.esm-browser.js(浏览器原生 ESM)、unpkg/jsdelivr指向dist/vuex.global.js(CDN 直接引入)。此外,本仓库还提供dist/vuex.mjs(见 package.json 的exports.import与 src/index.mjs 的 re-export 逻辑)用于 Node ESM 场景,并有 test/esm/esm-import.mjs 与 test/esm/esm-test.js 对其做端到端验证。

升级时建议检查自己的引入方式:凡是依赖 UMD 全局脚本加载方式的项目,需要改为 IIFE 的vuex.global.js,或改用打包器/ES Module 方案;生产环境务必切换到.prod产物。

破坏性变更四:createLogger从核心模块导出

在 Vuex 3 中,createLogger需要从vuex/dist/logger单独导入;Vuex 4 将其并入核心包,直接由vuex包导出:

import { createLogger } from 'vuex'

对应地,src/index.js 中createLogger./plugins/logger导入并随默认导出对象与命名导出一起暴露。升级时只需删除旧的vuex/dist/logger导入语句,统一从vuex导入即可。

createLogger本身提供了丰富的日志控制选项,实现位于 src/plugins/logger.js,各参数及其默认值如下:

参数默认值作用
collapsedtrue是否折叠 console 分组(groupCollapsedvsgroup
filter(mutation, stateBefore, stateAfter) => true过滤哪些 mutation 需要记录
transformerstate => state输出前转换 state(如序列化为 JSON)
mutationTransformermut => mut输出前转换 mutation 记录
actionFilter(action, state) => true过滤哪些 action 需要记录
actionTransformeract => act输出前转换 action 记录
logMutationstrue是否记录 mutation
logActionstrue是否记录 action
loggerconsole自定义日志对象

其实现通过store.subscribe订阅 mutation、通过store.subscribeAction订阅 action,每次变更时深拷贝前后 state,并以%c样式输出 prev state、mutation、next state 三行,便于在 Vue Devtools 之外快速定位状态变更链路。

新特性:useStore组合式函数

Vuex 4 新增了面向 Composition API 的useStore函数,用于在组件的setup钩子中获取 store 实例:

import { useStore } from 'vuex' export default { setup () { const store = useStore() // store.state.count / store.getters / store.commit / store.dispatch ... } }

useStore的底层实现非常简单,本质是对 Vue 3inject的封装(src/injectKey.js):

export const storeKey = 'store' export function useStore (key = null) { return inject(key !== null ? key : storeKey) }

它从组件树上注入由Store.installapp.provide(injectKey || storeKey, this))提供的 store 实例。默认使用内置的storeKey(字符串'store');在 TypeScript 项目中,可以传入自定义的InjectionKey<Store<State>>以获得类型完整的 store,该 key 需要在安装时一并传入app.use(store, key),详细做法见 docs/guide/typescript-support.md。

setup中使用 store 的完整姿势如下(见 docs/guide/composition-api.md):

import { computed } from 'vue' import { useStore } from 'vuex' export default { setup () { const store = useStore() return { // 用 computed 保持响应式 count: computed(() => store.state.count), double: computed(() => store.getters.double), // 提交 mutation 与派发 action increment: () => store.commit('increment'), asyncIncrement: () => store.dispatch('asyncIncrement') } } }

仓库中的 examples/composition 目录提供了完整的 Composition API 示例应用(counter、chat、shopping-cart、todomvc 等),例如 examples/composition/counter/store.js 展示了createStore+useStore的最小闭环用法,是迁移后验证新 API 的良好参照。

迁移自检清单

完成上述改造后,建议按以下清单逐项确认:

  1. 创建与安装new Vuex.Store(...)已替换为createStore(...)Vue.use(Vuex)已替换为app.use(store),且app.use(store)app.mount()之前调用。
  2. TypeScript 类型:已添加模块扩充声明文件(vuex-shim.d.tsvuex.d.ts),this.$storeuseStore()均获得正确类型;类型测试可参考 types/test/index.ts。
  3. 构建产物:确认所引用的 bundle 是 Vue 3 对齐后的新命名(vuex.global.jsvuex.esm-browser.jsvuex.esm-bundler.jsvuex.cjs.js),生产环境使用.prod变体;若通过 CDN 引入,注意 Global 构建已从 UMD 改为 IIFE。
  4. 日志插件createLogger已从vue包导入(import { createLogger } from 'vuex'),旧路径vue/dist/logger已移除。
  5. Vue 版本:Vuex 4 的 peer dependency 为 Vue^3.2.0(见 package.json),请确保项目中的 Vue 版本满足该要求;在升级 Vuex 前应先完成 Vue 2 → Vue 3 的迁移。

最后提醒:迁移文档对应的进一步阅读入口为 docs/guide/typescript-support.md 与 docs/guide/composition-api.md,安装方式参见 docs/installation.md。官方建议在 Vuex 4 迁移时尽量以createStore+useStore的新风格书写新代码,将旧的 Options API 风格代码逐步收敛到新 API 上。

【免费下载链接】vuex🗃️ Centralized State Management for Vue.js.项目地址: https://gitcode.com/gh_mirrors/vu/vuex

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 3:23:19

UE5运行时FBX导入:FBX SDK与ProceduralMeshComponent实战解析

1. 先交代背景&#xff1a;为什么一个“导入模型”功能要自己写去年在数字孪生项目里被一个需求卡了好几天&#xff1a;要在UE5项目里实现运行时动态导入FBX模型&#xff0c;用户点一个按钮就能把本地FBX放进场景&#xff0c;而不是像传统做法那样在编辑器里导入。当时第一反应…

作者头像 李华
网站建设 2026/9/19 3:23:11

Qt 5.14.2在aarch64上的静态交叉编译完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 3:22:40

腾讯云AIGC短漫剧全链路方案:从剧本到成片的实战拆解

腾讯云的AIGC短漫剧方案最近在行业里讨论度很高&#xff0c;很多做短剧、漫剧、甚至动画番剧的团队都在关注。说实话&#xff0c;市面上讲AI视频生成、讲大模型应用的文章已经很多了&#xff0c;但真正把“从剧本到成片”的全链路打通、并且拿出真金白银的成本账来聊的&#xf…

作者头像 李华
网站建设 2026/9/19 3:20:59

AI驱动的游戏出海增长:从买量优化到专属语言引擎实践

过去几年&#xff0c;我踩过最深的坑&#xff0c;就是把“游戏出海”这四个字理解成“把游戏翻译成外语再买量”。直到项目数据连续三个月原地踏步&#xff0c;我才真正意识到&#xff0c;出海的瓶颈从来不是预算不够&#xff0c;而是买量的边际效率在肉眼可见地衰减&#xff0…

作者头像 李华
网站建设 2026/9/19 3:20:55

读书笔记App开发实战:Room表结构、防抖保存与FTS检索

简介&#xff1a;一份基于Android平台的读书笔记App毕业设计论文文档&#xff0c;面向高校计算机专业学生与Android开发初学者&#xff0c;采用Java语言开发设计&#xff0c;解决了传统Web应用只能在PC机上使用、无法随时随地阅读的问题。文档从选题背景、研究现状出发&#xf…

作者头像 李华