背景
当我们使用vuex进行状态管理的时候,我们总是会看到一句话更改Vuex 的store 中的状态的唯一方法是提交commit
zongz,那么我们不提交commit
就没法修改state的值的了吗?其实是不对的,我们也可以通过下面的方法进行state值的修改。
this.$store.state.aaa = xxx
并且我们发现直接修改state
时,store
中的state
能够改变,并且是响应式的,并没有报错。但是为啥文档还要强调我们修改state
的唯一方式是提交commit
呢?
当我们将vuex
的模式改成严格模式的时候,我们在通过直接修改state
的方式修改状态的时候,控制台会报错。
官方文档中也进行了描述
开启严格模式,仅需在创建 store 的时候传入 strict: true;在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
解答
使用commit提交状态修改是为了配合开发者工具使用,使得状态更好的被最终,保存状态快照,实现时间漫游/回滚之类的操作。
其实官方文档有很好的解释
这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。
源码分析
首先我们看看当我们开启严格模式后,vuex是怎么处理的
开启严格模式后我们将执行enableStrictMode
函数,这个函数内部通过watch来判断state的更新,当state变化后,如果是非生产模式,判断store._committing
的值来是否抛错。
我们发现store._committing
的默认值是false
,那么默认情况下,当state
改变后必然是会抛错的。
我们接下来看看通过commit
来修改state
的逻辑
我们发现,当通过commit
来进行状态修改的时候,会将_committing
设置为true
,这样就不会进行报错了。
总结
根据上面的分析,开发模式的时候,我们在使用vuex的时候最好设置成严格模式,修改state的时候我们不要直接修改,而是通过commit来提交。主要是为了状态能够很好的跟踪,开发者工具更好的处理状态变化,更好的调试体验。