vuex中直接修改state 与 commit来修改state的区别

2,342 阅读2分钟

这是我参与更文挑战的第17天,活动详情查看更文挑战

背景

当我们使用vuex进行状态管理的时候,我们总是会看到一句话更改Vuex store 中的状态的唯一方法是提交commitzongz,那么我们不提交commit就没法修改state的值的了吗?其实是不对的,我们也可以通过下面的方法进行state值的修改。

his.$store.state.aaa = xxx

并且我们发现直接修改state时,store中的state能够改变,并且是响应式的,并没有报错。但是为啥文档还要强调我们修改state的唯一方式是提交commit呢?

当我们将vuex的模式改成严格模式的时候,我们在通过直接修改state的方式修改状态的时候,控制台会报错。

官方文档中也进行了描述

开启严格模式,仅需在创建 store 的时候传入 strict: true;在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

解答

使用commit提交状态修改是为了配合开发者工具使用,使得状态更好的被最终,保存状态快照,实现时间漫游/回滚之类的操作。

其实官方文档有很好的解释

这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。

源码分析

首先我们看看当我们开启严格模式后,vuex是怎么处理的

微信图片_20210624225058.png

微信图片_20210625231804.png

微信图片_20210625231808.jpg 开启严格模式后我们将执行enableStrictMode函数,这个函数内部通过watch来判断state的更新,当state变化后,如果是非生产模式,判断store._committing的值来是否抛错。

我们发现store._committing的默认值是false,那么默认情况下,当state改变后必然是会抛错的。

我们接下来看看通过commit来修改state的逻辑

微信图片_20210625232056.jpg

微信图片_20210625232103.png

我们发现,当通过commit来进行状态修改的时候,会将_committing设置为true,这样就不会进行报错了。

总结

根据上面的分析,开发模式的时候,我们在使用vuex的时候最好设置成严格模式,修改state的时候我们不要直接修改,而是通过commit来提交。主要是为了状态能够很好的跟踪,开发者工具更好的处理状态变化,更好的调试体验。