VuePack状态管理实战:借助 Counter 示例彻底搞懂 Vuex、mutations 与 actions
【免费下载链接】vuepack:package: A modern starter which uses Vue 2, Vuex, Vue-router and Webpack 2 (and even Electron)项目地址: https://gitcode.com/gh_mirrors/vu/vuepack
VuePack 是一个现代化的 Vue 2 脚手架项目,开箱即用 Vue 2、Vuex、Vue Router 和 Webpack 2。本文将通过 VuePack 内置的 Counter 计数器示例,带你从零搞懂 Vuex 状态管理的三大核心概念:state、mutations 与 actions,并学会把它们接入到自己的 Vue 应用中。
📦 为什么选择 VuePack 来学习 Vuex?
很多新手学 Vuex 喜欢凭空搭项目,结果卡在配置上。而 VuePack 已经把 vuex 和 vuex-router-sync 写进了依赖,store、router、组件全部预配置好:
- Vue 2 + Vuex 2 + Vue Router完整全家桶
- 热重载:修改 store 文件,页面状态立即响应
- JSX 与单文件组件双写法:同一个 Counter 组件同时提供 JSX 版本 和 Counter.vue 版本,方便对照学习
- 可选支持 Electron、ESLint、PostCSS 等,详见 docs/ 目录
也就是说,你可以跳过所有环境配置,直接读懂状态管理是怎么跑起来的。
🧩 Counter 示例:一个按钮看懂三种操作
Counter 组件是 VuePack 状态管理的"演示窗口",它在 首页视图 中被渲染。界面上有一个大数字,以及三个按钮:
| 按钮 | 触发的 Vuex 操作 | 对应代码 |
|---|---|---|
| Increment | commit('INCREMENT') | 同步 +1 |
| Decrement | commit('DECREMENT') | 同步 -1 |
| Increment Async | dispatch('incrementAsync') | 异步 +1 |
在 JSX 版本的 Counter 组件 中,三个方法一一对应:
increment() { this.$store.commit('INCREMENT') } decrement() { this.$store.commit('DECREMENT') } incrementAsync() { this.$store.dispatch('incrementAsync') }记住两个动词就够用了:
- commit→ 提交 mutation(同步)
- dispatch→ 派发 action(异步)
🗃️ state 与 mutations:同步改数据的正确姿势
打开 store 入口文件,整个 Vuex 实例只有 33 行代码。
1️⃣ state:唯一的数据源
const state = { count: 0 }Vuex 的核心思想是Single Source of Truth:所有需要共享的数据都集中在 state 里。Counter 组件展示的数字,就是直接读取this.$store.state.count(见 Counter 渲染部分)。组件不自己持有数字,只"引用"store——这就是响应式的来源,state 一变,界面自动更新。
2️⃣ mutations:修改 state 的唯一入口
const mutations = { INCREMENT(state) { state.count++ }, DECREMENT(state) { state.count-- } }新手最常犯的错误是"直接在组件里改 state"。Vuex 禁止这种做法,所有修改必须走 mutations,带来两个好处:
- 可追踪:每次变更都有明确的方法名,调试时一目了然
- 可 DevTools 支持:变更以"提交记录"形式被捕获
Counter.vue 单文件版本 演示了更简洁的写法——直接在模板上@click="$store.commit('INCREMENT')",连 methods 都省了。
⚡ actions:处理异步逻辑的规范写法
mutations 里不允许异步操作。那"延时加 1"、"请求接口后更新数据"这类逻辑放哪?答案是 actions。
看 store 中的 actions 定义:
const actions = { incrementAsync({ commit }) { setTimeout(() => { commit('INCREMENT') }, 200) } }这里体现了一条清晰的分工链:
按钮 dispatch('incrementAsync') → action 处理等待 200ms 的异步逻辑 → action 内部 commit('INCREMENT') → mutation 真正修改 state → 界面数字更新记忆口诀:actions 负责"做事"(异步流程),mutations 负责"改数"(同步变更)。你以后写接口请求、轮询、延时任务,都套这个模式即可。
🔗 三步把 store 接入你的 Vue 应用
理解组件之后,看看 store 是如何"通电"到整个应用的。入口是 app.js:
- 导入 store 与 router:
import store from './store' - 同步路由与状态:
sync(store, router)——由 vuex-router-sync 完成,让 store 里能感知当前路由,这对"根据登录路由恢复状态"这类场景非常有用 - 注入根实例:
new Vue({ router, store, ...App })
只要 store 挂在了根实例上,任意子组件都能通过this.$store访问,这就是 Counter 组件无需 import 也能用 $store 的原因。
🛠️ 动手练习:给你的 Counter 加一个"重置"功能
按下面三步扩展,验证你是否真的掌握了 Vuex 三件套:
- 在 store 文件 的 mutations 中新增
RESET(state) { state.count = 0 } - 在 Counter 组件 的 methods 中新增
reset() { this.$store.commit('RESET') } - 在渲染函数里加一个 Reset 按钮绑定该方法
如果想更进一步,可以写一个 action 模拟"从服务器加载初始值"(参考incrementAsync的写法)。保存后热重载会自动生效,数字会立刻归零。
📝 小结
| 概念 | 一句话理解 | 本项目示例 |
|---|---|---|
| state | 数据仓库 | count: 0 |
| mutations | 同步修改的唯一入口 | INCREMENT/DECREMENT |
| actions | 异步逻辑的容器 | incrementAsync |
| commit / dispatch | 组件调用 store 的两个动词 | Counter 的三个按钮 |
VuePack 用 33 行的 store + 一个 Counter 组件,浓缩了 Vuex 最核心的设计哲学。把它跑起来、改一改,你就已经具备了在真实项目中使用 Vuex 的能力。
【免费下载链接】vuepack:package: A modern starter which uses Vue 2, Vuex, Vue-router and Webpack 2 (and even Electron)项目地址: https://gitcode.com/gh_mirrors/vu/vuepack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考