Vuex 4 入门详解:Vue 3 应用中的集中式状态管理
Vuex 4 入门详解Vue 3 应用中的集中式状态管理【免费下载链接】vuex️ Centralized State Management for Vue.js.项目地址: https://gitcode.com/gh_mirrors/vu/vuex本文以 Vuex 官方文档的“什么是 Vuex”一章docs/ja/index.md该文档面向基于 Vue 3 运行的 Vuex 4为核心系统讲解 Vuex 作为“状态管理模式 库”的基本理念、单向数据流的三要素、共享状态为何必须集中管理并结合当前仓库源码src/store.js、src/store-util.js验证这些理念在 Vuex 4 中的具体落地方式。读完本文你将理解 Vuex 的设计动机、Store 的创建与响应式原理、commit/dispatch 的同步异步边界并能在中大型 Vue 3 应用中做出是否引入 Vuex 的合理判断。需要先说明版本前提当前仓库的版本为4.1.0其peerDependencies要求vue^3.2.0见 package.json即本文全部结论适用于Vuex 4 Vue 3组合面向 Vue 2 的 Vuex 3 是另一套文档与 API不在本文讨论范围内。Vuex 是什么一句话定义Vuex 是 Vue.js 应用的状态管理State Management模式 库。它通过强制两条规则来实现可预测性状态只能通过预测可追踪的方式被改变即必须经由同步的 mutation 修改它充当应用中所有组件共享的集中式 Store。从源码结构看Vuex 对外导出的 API 面非常克制。入口文件 src/index.js 只导出 9 个成员API类型作用Store/createStore类 / 工厂函数创建 Store 实例useStore/storeKey函数 / SymbolComposition API 下注入与获取 StoremapState/mapMutations/mapGetters/mapActions辅助函数把 Store 内容映射为组件的 state/methodscreateNamespacedHelpers辅助函数为命名空间模块批量生成映射辅助函数createLogger插件开发环境记录 mutation 日志见 src/plugins/logger.js也就是说所谓“状态管理库”在代码层面就是createStore返回的Store实例外加一组帮助你在组件中消费 Store 的工具函数。状态管理模式的三要素从一个计数器开始理解 Vuex 之前先看一个不依赖任何库的极简 Vue 计数器const Counter { // state data () { return { count: 0 } }, // view template: div{{ count }}/div , // actions methods: { increment () { this.count } } } createApp(Counter).mount(#app)这个组件内部其实包含了状态管理的三个基本要素状态State驱动应用的可信信息源the source of truth视图View对状态的一种声明式映射动作Action响应视图中的用户输入从而触发状态变更的方式。它们共同构成“单向数据流”这一概念的最小责任划分数据只能沿 State → View → Action → 修改 State 的方向流动视图不直接写状态用户输入通过 action 间接落到状态上。这一约定让数据变化可追踪、可复现。共享状态为何需要集中管理单向数据流的简洁性在多个组件需要共享同一状态时立刻遭遇瓶颈典型场景有两种多个视图依赖同一状态若只用 props 向下传递在深层嵌套的组件树里逐层传 props 非常繁琐而且对兄弟组件完全不适用props 只能自上而下不同视图的动作需要修改同一状态常见“土办法”是直接引用父/兄弟组件实例或通过事件在多份状态副本之间手动同步——这些模式都很脆弱很快就会演变成难以维护的代码。解决思路是把共享状态从组件中抽取出来交给一个全局单例管理组件树整体变成一个巨大的“视图”任意深度的组件都能访问同一份状态任何组件都能触发修改状态的动作同时把状态管理相关的概念state / mutation / action / getter显式地定义、分离并施加规则代码结构与可维护性随之提升。这正是 Vuex 的基本思想。它的理念明显受到 Flux、Redux 和 The Elm Architecture 的影响但与其他通用模式的关键差异在于Vuex 是专门为 Vue.js 的细粒度响应式系统调优过的库——它借用 Vue 的依赖追踪与更新调度来实现高效更新而不是像部分 Flux 系框架那样依赖整体重绘。这一点可以在源码中得到直接印证见下一节。源码印证Vuex 4 如何实现这套理念1. 创建 StorecreateStore只是一个语法糖src/store.js 中export function createStore (options) { return new Store(options) }Store构造函数src/store.js#L19-L76完成四件事恰好对应状态管理模式的几个关注点constructor (options {}) { const { plugins [], strict false, devtools } options // ① 内部表mutation / action / getter 注册表、模块树、订阅者列表 this._mutations Object.create(null) this._actions Object.create(null) this._wrappedGetters Object.create(null) this._modules new ModuleCollection(options) // 模块树 ... // ② 绑定 commit / dispatch保证以 store 为 this 调用 this.dispatch function boundDispatch (type, payload) { ... } this.commit function boundCommit (type, payload, options) { ... } // ③ 初始化根模块递归注册所有子模块与 getter installModule(this, state, [], this._modules.root) // ④ 建立响应式状态 计算 getter然后逐个应用插件 resetStoreState(this, state) plugins.forEach(plugin plugin(this)) }注意commit与dispatch在构造时就被包装为始终指向该 store 实例的绑定函数这意味着你可以在组件里把this.$store.commit直接解构传给其他模块而不会丢失上下文。2. 状态响应式把整棵 state 树包进reactive“利用 Vue 的响应式系统”这句宣传语落在 src/store-util.js#L60-L62store._state reactive({ data: state })整个 state 树被包进 Vue 3 的reactive代理对象Store.state的 getter 再返回this._state.datasrc/store.js#L91-L93。由此带来两个行为特征细粒度更新组件只读state.count时只订阅该属性count只触发依赖它的视图更新这正是文档所说“为高效更新而调优”的实现基础禁止直接赋值替换Store定义了set state (v)开发环境下直接执行store.state xxx会断言失败提示改用store.replaceState()src/store.js#L95-L99、L215-L219——保证状态只能作为整体树被受控地替换而不是被悄悄换掉引用。此外strict: true选项会在开发环境注册一个deep: true, flush: sync的 watchersrc/store-util.js#L271-L277只要 state 在非 mutation 期间_committing false被修改就断言报错“do not mutate vuex store state outside mutation handlers”。这是“只能通过预测可追踪方式改变状态”这条规则的运行时强制。3. Getters用computedEffectScope实现缓存派生状态Getter 本质是带缓存的派生状态。src/store-util.js#L42-L58 显示每个 getter 被包成 Vue 的computedconst scope effectScope(true) // detached scope scope.run(() { forEachValue(wrappedGetters, (fn, key) { computedObj[key] partial(fn, store) computedCache[key] computed(() computedObj[key]()) Object.defineProperty(store.getters, key, { get: () computedCache[key].value, enumerable: true }) }) })这里有个值得注意的工程细节computed被创建在一个detached EffectScopeeffectScope(true)中。源码注释解释得很清楚——如果不这样做getter 的 effect 会跟随某个组件的作用域组件卸载时 computed 就会被销毁导致其他组件再访问该 getter 时失效。Vuex 特意用独立作用域托管 getter保证它们的生命周期与 Store 一致。4.commit与dispatch同步与异步的边界这是 Vuex 规则体系的核心实现对比两个方法可以看出边界设计commit(type, payload)src/store.js#L101-L136同步查表this._mutations[type]未注册的类型在开发环境打console.error后静默返回随后在_withCommit包裹内逐个执行 handler最后通知subscribe的订阅者。整个流程没有 Promise保证了 mutation 的同步性与可记录性dispatch(type, payload)src/store.js#L138-L197查this._actions[type]支持多个同名 action handler 并行执行entry.length 1时用Promise.all归并并始终返回 Promise——action handler 无论返回什么都会被包成 Promise见 src/store-util.js#L240-L242因此 action 天然适合承载异步操作同时暴露了subscribeAction的before/after/error三个钩子形成对 action 全生命周期的观测点。action handler 收到的上下文由 src/store-util.js#L229-L252 构造包含模块级的dispatch、commit、state、getters以及全局的rootState、rootGetters——这就是后文模块示例中解构参数({ commit, state })的来源。5. 注入应用app.use(store)背后发生了什么install (app, injectKey) { app.provide(injectKey || storeKey, this) // inject 注入 app.config.globalProperties.$store this // Options API 的 this.$store const useDevtools this._devtools ! undefined ? this._devtools : __DEV__ || __VUE_PROD_DEVTOOLS__ // 默认开发环境启用 DevTools if (useDevtools) { addDevtools(app, this) } }src/store.js#L78-L89即一次app.use(store)同时打通了 Options APIthis.$store与 Composition APIinject(storeKey)/useStore()两条消费路径并在默认情况下挂载vue/devtools-api驱动的 DevTools 集成——这也是 package.json 中唯一运行时依赖vue/devtools-api的用途。最小可用示例仓库内置的计数器上述原理在仓库的示例中都能直接对应。examples/classic/counter/store.js 创建了一个完整 Storeimport { createStore } from vuex // 根 state 对象每个 Vuex 实例就是一棵单一 state 树 const state { count: 0 } // mutations真正修改状态的操作必须是同步的可被插件记录用于调试 const mutations { increment (state) { state.count }, decrement (state) { state.count-- } } // actions可产生副作用、可包含异步操作的函数 const actions { increment: ({ commit }) commit(increment), decrement: ({ commit }) commit(decrement), incrementIfOdd ({ commit, state }) { if ((state.count 1) % 2 0) { commit(increment) } }, incrementAsync ({ commit }) { return new Promise((resolve, reject) { setTimeout(() { commit(increment) resolve() }, 1000) }) } } // getters派生状态的纯函数 const getters { evenOrOdd: state state.count % 2 0 ? even : odd } export default createStore({ state, getters, actions, mutations })组件侧的接入只有三步examples/classic/counter/app.jsimport { createApp } from vue import Counter from ./Counter.vue import store from ./store const app createApp(Counter) app.use(store) // 触发 install()provide 挂载 $store DevTools app.mount(#app)对照源码可以看出示例与实现的精确对应关系incrementAsync里的setTimeout正是 action 承载异步、mutation 保持同步的分工({ commit, state })解构的就是registerAction注入的上下文而evenOrOdd这个 getter 最终会以computed缓存的形式挂在store.getters上。仓库中还有 Composition API 风格的同款示例examples/composition/counter/store.js以及更复杂的购物车、聊天示例可作为进一步阅读的路径。何时该用 Vuex官方文档给出了清醒的判断标准Vuex 能帮你管理共享状态但也要付出概念和样板代码的成本这是短期生产力与长期生产力的权衡。如果你的应用规模不大、没有中大型 SPA 级别的复杂度引入 Vuex 只会显得冗长很多时候一个手写的简单 store 模式组件外部的 reactive 对象 修改函数就够了不需要引入完整库如果你正在构建中大型 SPA组件外状态开始难以组织多组件读写同一数据、跨层级更新、调试困难Vuex 就是下一步的合理选择。Redux 的作者 Dan Abramov 有一句被文档引用的经典评价Flux 库就像眼镜一样当你发现自己需要它们的时候你自然就会知道。把它翻译成工程决策语言就是不要为了用而用而是当“多份状态副本手动同步”“props 层层透传”“组件间直接引用”这类坏味道反复出现时集中式 Store 的抽象收益才会超过它的样板成本。同时要注意 Vuex 4 的适用前提它运行在 Vue 3 上peerDependencies: vue^3.2.0其install(app)注入方式、useStore/storeKey的 Composition API 支持、vue/devtools-api集成都是 Vue 3 生态的产物如果你维护的是 Vue 2 项目应使用 Vuex 3 及其对应文档两套 API 存在不兼容差异可参考仓库文档中的迁移章节 docs/ja/guide/migrating-to-4-0-from-3-x.md。小结回顾本文从 docs/ja/index.md 展开的完整脉络概念层Vuex 状态管理模式 库三要素State / View / Action构成单向数据流规则保证变更可预测动机层props 透传与事件同步在共享状态下失效抽取为全局单例 Store 是结构化解法实现层仓库源码证据state 树被reactive包装获得细粒度响应式src/store-util.js#L60-L62getter 由computed 独立EffectScope承载src/store-util.js#L42-L58commit同步、dispatch异步返回 Promisesrc/store.js#L101-L197app.use(store)一次打通 Options API 与 Composition API 两条消费路径src/store.js#L78-L89决策层Vuex 的价值与项目规模正相关按“眼镜理论”在共享状态复杂度超过手写方案可承受范围时引入。掌握这条“理念 → 动机 → 实现 → 决策”的链条后继续阅读仓库中的状态docs/ja/guide/state.md、mutationdocs/ja/guide/mutations.md、模块docs/ja/guide/modules.md等后续章节时每个概念都能在当前仓库的源码中找到落点。【免费下载链接】vuex️ Centralized State Management for Vue.js.项目地址: https://gitcode.com/gh_mirrors/vu/vuex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Lenis:轻量级平滑滚动库手册——3 个核心机制 + 4 个实战场景 + 配置速查

Lenis:轻量级平滑滚动库手册——3 个核心机制 + 4 个实战场景 + 配置速查

Lenis:轻量级平滑滚动库手册——3 个核心机制 4 个实战场景 配置速查 【免费下载链接】lenis Smooth scroll as it should be 项目地址: https://gitcode.com/GitHub_Trending/le/lenis Lenis 是一款轻量级、零依赖的平滑滚动库,仅数 KB 体积&a…

2026/9/23 6:23:02 阅读更多 →
降AI率全指南:从检测原理到8款工具评测与人工润色技巧

降AI率全指南:从检测原理到8款工具评测与人工润色技巧

1. 别急着找工具:先搞懂降AI率到底在降什么每次期末季,总能在各种群里看到有人问“有没有靠谱的降AI率工具”。尤其本科生写课程论文、毕业设计开题报告的时候,辛辛苦苦写了三千字,丢进查重系统一看,红字标得触目惊心&…

2026/9/23 4:51:14 阅读更多 →
Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI

Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI

Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI 【免费下载链接】Noi 🚀 Less chaos. More flow. 项目地址: https://gitcode.com/GitHub_Trending/no/Noi 需要向ChatGPT、Claude、通义千问等多个AI平台索要同一问题的答案时,N…

2026/9/23 5:26:29 阅读更多 →

最新新闻

照着用就行:AI论文写作工具2026最新测评与推荐

照着用就行:AI论文写作工具2026最新测评与推荐

2026年真正好用的AI论文写作工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …

2026/9/23 9:06:23 阅读更多 →
3 分钟画出第一张流程图:Mermaid 在线编辑器 mermaid-live-editor 新手实战手册

3 分钟画出第一张流程图:Mermaid 在线编辑器 mermaid-live-editor 新手实战手册

3 分钟画出第一张流程图:Mermaid 在线编辑器 mermaid-live-editor 新手实战手册 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trendin…

2026/9/23 9:06:23 阅读更多 →
从“信任边界“视角看广电嵌入式终端安全缺陷挖掘思路

从“信任边界“视角看广电嵌入式终端安全缺陷挖掘思路

从"信任边界"视角,浅析广电嵌入式终端的安全缺陷挖掘思路阅读提示:本文对涉及的设备与系统均做脱敏处理——不出现厂商名称、产品型号、真实接口路径、账号凭据与网络拓扑。文中代码为示意性伪代码,非现场原文。所述缺陷已通过国家…

2026/9/23 9:06:23 阅读更多 →
3个步骤搞定药柜管理系统,源码解析带你避坑

3个步骤搞定药柜管理系统,源码解析带你避坑

3个步骤搞定药柜管理系统,源码解析带你避坑 刚学完 Python 或 Java 基础语法,代码能跑通,但一面对“药柜”这种具体业务需求就脑子发懵?别慌,这是从“写代码”到“做项目”的典型断层。很多人卡在不知道如何把零散的…

2026/9/23 9:06:23 阅读更多 →
搞定伟大的项目架构:3个步骤告别代码堆砌

搞定伟大的项目架构:3个步骤告别代码堆砌

搞定伟大的项目架构:3个步骤告别代码堆砌 学会语法却不知怎么搭项目,这是无数开发者卡脖子的真问题。刚跑通 Hello World,面对真实业务需求就懵了,代码写得像面条,改一处崩全身。别慌,这恰恰是从“写代码的人”到“做项目的人”的分水岭。…

2026/9/23 9:06:23 阅读更多 →
移居其一避坑指南:3个关键优化让项目跑飞

移居其一避坑指南:3个关键优化让项目跑飞

移居其一避坑指南:3个关键优化让项目跑飞 看了一堆教程还是不会写项目?别慌,这恰恰是大多数人的通病。理论都懂,代码一敲就错,项目一跑就卡。今天这篇避坑指南,不讲虚的,直接拿一个真实场景——“移居其一”数据处理——来拆解性能优化的全流程。…

2026/9/23 9:05:21 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →