为什么vuex的state在vue实例中要用commit来改变,直接用赋值改变值会有什么弊端吗?

之前阅读官方文档时,了解到当要改变vuex的state的时候必须要用commit来提交一个mutation,像这样:

this.$store.commit("someState",...)
//或者
this.$store.dispatch("changeSomeState",...)

但是一个刚接触vue的朋友在写代码的时直接使用赋值的形式来改变state,像这样

this.$store.state[someState] = XXX

也能够成功完成他想要的效果,

那么请问,

这里的官方文档中说的必须要使用commit提交一个Mutation来改变state,是仅仅需要一个规范来代码可读性或者说明确每个状态改变的地方,还是说有其他的作用,直接赋值会有什么弊端吗?

阅读 7.9k
3 个回答

从效果上来说没有影响但是不建议这么做.谈一下我的理解.

vuex 从功能上来说就是一个前端缓存系统.
解决了 SPA 不同组件之间数据共享的问题

那么到底如何用,为什么会存在 mutation 等概念呢?

你可以看一下官方文档示例 shopping-cart.

这个范例模拟电商中,添加商品到购物车,并进行结算的逻辑.
核心逻辑包括.

  1. 拉取产品列表并显示
  2. 点击添加到购物车
  3. 进行结算.

站在用户的角度,用户只做了两件事

  1. 将商品添加到购物车
  2. 结算

在这里,添加商品会修改购物车的显示.
最简单的做法就把这些数据都放在父组件.

但是看一下官方示例如何实现的.
定义了两个组件

那么组件数据呢?全部放在了 vuex 中进行管理.
为什么要这么做,为什么不直接放在父组件里面呢?

  1. 更清晰的代码结构,每个组件都有自己的职责,不必为了实现不同组件之间的交互而定义额外的数据总线或产生一个数据庞大的父组件来作为周转
  2. 可复用的逻辑,将常用的业务利用 vuex 拆分成基于状态而非过程控制的代码.
  3. ...

我们把上面的逻辑利用状态图表示
图片描述

可以看到这个逻辑异常清晰.

在回到问题本身直接修改有什么危害?

从功能上说没有危害,但是从代码构建角度是没有理解 vuex 这个神器怎么用!!!
不要只把 vuex 当做一种全局修改数据的工具.它的意义在于
把跨组件的交互拆分为基于状态管理的处理模式,是更高层的逻辑抽象

针对此提一下一些使用技巧.
下回在用 vuex 时考虑如下问题:

  1. 对于用户层暴露的逻辑事件是什么?

    看购物车可已看出就两个事件,添加商品,和结算
  2. 这个事件会影响那些数据

然后把状态图画出来,利用 vuex 中的语法编写.

回到上面问题,假设现在用户的购物车添加了收藏,取消等逻辑,此时对于你而言只是单纯的增加了 mutations 和相关事件的状态处理.数据结构并没有变化,这就是好的设计,

一楼说的很详细了
补充一下个人观点

使用如vuex,redux本身就是希望基于这样一个数据结构的约定,使得项目代码更加直观和简单

所谓直观和简单是说:
每一个状态树对应整个项目的一个状态,而每次Mutation则代表了一次项目状态的改变,为了能够更加直观地观察到这样的变化(使得我们能够迅速追踪或者说发现项目状态的变化),我们使用flux这样的框架思想去约定变化,使我们看代码时一眼就能看出,这是一次状态树的变化

更贴合实际的一个例子就是
当我们的项目出现bug时,要追踪某一时刻查看在哪个过程中state的某个值出现了问题,我们可以直接去约定的mutation-type表中去找每次状态的变化,变了什么或者说是怎么变的,方便更快速地定位问题和分析问题

个人觉得
如果不想使用这样的约定,就不要用vuex,redux之类,直接在根入口自定义一个全局空间,其他子模块统一访问全局空间就行了

就使用vue-devtools来说,直接给state赋值,在浏览器控制台上不会显示修改记录。而通过commit来修改state,会在浏览器控制台上清楚的看到每一个state属性修改的详细的记录。
image.png
image.png
image.png
image.png
如果在某个state属性没有同步到页面上,不知道是自己程序逻辑还是vuex赋值出了问题。就直观使用来说,使用commit的方法能更方便程序的调试

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进