大家好,我是小杨,一个被Vuex虐过千百遍的前端老司机。今天咱们来聊聊Vuex里最让人困惑的两个概念------mutations和actions。为啥非要分开?为啥不能在mutations里写异步?看完这篇你就全明白了!
1. mutations:唯一能改state的"会计"
记得我刚用Vuex时,觉得mutations这玩意儿真多余,直接改state不香吗?后来项目出bug了才明白它的重要性。
mutations的核心特点:
- 唯一能修改state的地方(财务部独享修改权限)
- 必须是同步函数(所有修改都要记录在案)
- 通过commit触发(要走正规流程)
javascript
// store/modules/user.js
const mutations = {
// ✅ 正确的mutation
SET_USER(state, user) {
state.user = user
},
// ❌ 错误示范(虽然能运行,但违背设计原则)
async SET_USER_ASYNC(state, user) {
await someAsyncOperation()
state.user = user // 千万别这么干!
}
}
2. actions:处理异步的"业务员"
actions就像公司的业务部门,专门处理各种外部对接:
actions的核心特点:
- 可以包含异步操作(跟API打交道)
- 不能直接修改state(没财务权限)
- 通过dispatch触发(业务部门的工作流程)
javascript
const actions = {
async login({ commit }, credentials) {
try {
const user = await api.login(credentials) // 异步请求
commit('SET_USER', user) // 走正规流程修改state
return user
} catch (error) {
console.error('登录失败', error)
throw error
}
}
}
3. 为啥非要分开?一次惨痛的教训
去年我做了一个电商项目,当时图省事在mutation里调接口:
javascript
// ❌ 灾难性写法
mutations: {
async GET_PRODUCTS(state) {
state.loading = true
const res = await api.getProducts() // 异步请求
state.products = res.data
state.loading = false
}
}
结果出现两个致命问题:
- DevTools无法正确追踪状态变化
- 多个异步mutation导致状态更新顺序错乱
4. 官方为啥这么设计?
Vuex作者的设计意图其实很明确:
特性 | mutations | actions |
---|---|---|
能否修改state | ✅ 能 | ❌ 不能 |
同步/异步 | ❌ 必须同步 | ✅ 可以异步 |
触发方式 | commit | dispatch |
定位 | 状态变更记录 | 业务逻辑处理 |
5. 我的最佳实践
经过多年踩坑,我总结出这样的分工原则:
javascript
// 数据获取流程示例
actions: {
async fetchData({ commit }) {
commit('SET_LOADING', true) // mutation改状态
const data = await api.getData() // action处理异步
commit('SET_DATA', data) // mutation改状态
commit('SET_LOADING', false)
return data
}
},
mutations: {
SET_LOADING(state, isLoading) {
state.isLoading = isLoading
},
SET_DATA(state, data) {
state.data = data
}
}
6. 特殊场景处理
有时候我们确实需要在mutation之后执行一些操作,可以用subscribe:
javascript
// 在组件中监听mutation
this.$store.subscribe((mutation, state) => {
if (mutation.type === 'SET_USER') {
// 用户数据更新后的操作
localStorage.setItem('user', JSON.stringify(state.user))
}
})
7. 常见误区答疑
Q:我就是想在mutation里写异步,会怎样?
A:就像让会计去跑业务,短期可能没问题,但迟早会账目混乱!
Q:actions能直接改state吗?
A:技术上可以(通过this._vm),但千万别这么干,会破坏Vuex的可预测性
Q:小型项目也要这么严格吗?
A:养成分离的好习惯,项目大了才不会翻车
总结
记住这个黄金法则:
- mutations:只管同步修改state(财务)
- actions:处理异步和业务逻辑(业务)
就像公司要有明确的部门分工,Vuex也需要清晰的职责划分。现在你明白为啥Vuex要这么设计了吧?
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!