一. 使用vuex修改state时,有两种方式:
- 可以直接使用
this.$store.state.变量 = xxx; this.$store.dispatch('action中的方法名', payload)或者this.$store.commit('mutations中的方法名', payload)
但是官方文档中有这么一句话:
更改 Vuex 的 store 中的状态的唯一方法是提交
mutation。
二. 异同点
- 共同点: 能够修改 state 里的变量,并且是响应式的(能触发视图更新)
- 不同点:若将 vue 创建 store 的时候传入
strict: true, 开启严格模式,那么任何修改 state 的操作,只要不经过mutation的函数,vue 就会throw error :[vuex] Do not mutate vuex store state outside mutation handlers。
在vuex官方文档上看到了关于严格模式的描述:
开启严格模式,仅需在创建 store 的时候传入 strict: true;
在严格模式下,无论何时发生了状态变更且不是由
mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
三.使用commit修改state的优点:
vuex 能够记录每一次 state 的变化记录,保存状态快照,实现时间漫游/回滚之类的操作。(实际本人未用到,暂时未遇到使用该特性的需求)
四.代码对照示例
不推荐:直接修改
// 能改、能响应,但绕过了 Vuex 的追踪
this.$store.state.count = 10;
推荐:通过 commit 走 mutation
// 1. 定义 mutation
const store = new Vuex.Store({
state: { count: 0 },
mutations: {
setCount(state, val) {
state.count = val; // 唯一修改入口
},
},
});
// 2. 组件里提交
this.$store.commit("setCount", 10);
为什么推荐用 commit(即使没开严格模式)
- 可追踪 / 可调试:所有修改都经过
mutation,Vue DevTools 能记录每一次变更、做时间旅行调试(回滚、重放)。直接改就断了这条链。 - 集中管理:修改逻辑写在
mutations里,一眼能看出 state 是怎么变的;直接散落在组件里,后期难维护。 - 严格模式兜底:生产前开一次
strict: true跑一遍,能帮你揪出所有”偷偷直接改”的野路子代码。
补充:新项目现在官方更推荐 Pinia(Vuex 的继任者),语法更简洁、没有
mutations这个概念,直接state.xxx = xxx也受追踪。老项目沿用 Vuex 的话,还是走commit最稳。