Vuex-我可以在不创建突变的情况下更新状态的属性吗?

时间:2019-12-11 13:55:47

标签: vuex

我具有此状态storeMovement和一个用于更新此状态updateStoreMovement的突变

我正在使用mapState在我的vue组件中加载此状态,并使用this.storeMovement通过方法访问它

我想知道的是,如果我不使用突变而更新此状态的特定属性,会发生什么问题

this.storeMovement.steps = new_steps

这会传播到所有其他组件,而无需创建突变来更新此属性

这会在以后给我带来麻烦吗?

1 个答案:

答案 0 :(得分:1)

这里有几个不同的角度。

商店state中的对象将是反应性的,与组件data中的对象相同。该对象的读取属性将被跟踪,而写入新值将触发依赖关系。这只是Vue反应系统在做的事情。从反应性的角度来看,这家商店并没有真正参与其中。

因此,正如您所观察到的,您可以更新反应性对象的属性,一切似乎都可以正常更新。

道具也有类似现象。子组件不应更改prop值,如果尝试更改,则会出现警告消息。但是,如果prop值是一个反应性对象,则可以更改该对象的属性,并且一切似乎都可以正常工作。

那是什么问题?

在这两种情况下都有一个指导原则。数据只能由其所有者更新。在商店的情况下,所有者是商店或商店模块。对于道具,所有者是向下传递数据的上游组件。

为什么?

如果仅所有者更改数据,则更易于维护。如果该责任分散在多个地方,那么将来进行调试或更改将更加困难。尤其是,查找商店变异的所有用法通常很容易,而尝试查找到具有通用名称(例如name)的属性的任何地方都很难。

此外,这里假设对象是“根”数据。如果您以后决定该对象应该在计算属性或存储获取器中创建,而不是直接处于数据/状态中怎么办?突然,它不是反应对象,并且更改属性将无效。相反,您需要更新一些其他用于生成对象的基础属性。如果所有更新逻辑都在所有者中,则这样会更容易。

商店还有其他一些好处。

虽然商店没有直接参与反应性,但它​​确实有一个subscribe方法,插件可以使用该方法来跟踪何时调用了变异:

https://vuex.vuejs.org/api/#subscribe

如果您不进行任何突变,则不会通知使用这些事件的任何插件。例如,如果您正在使用插件将状态持久化为localStorage,那么突变之外的数据更改将不会持久化,至少不会立即持久化。如果页面刷新,则从localStorage加载的状态将是过时的。

同样,Vue DevTools支持称为 time-travel debugging 的东西。仅当您使用突变时,此方法才能正常工作。

如果您还不熟悉它,建议您使用严格模式:

https://vuex.vuejs.org/guide/strict.html

最后,我要指出该商店经常被滥用,我个人认为Vuex商店的设计必须为此承担一些责任。我相信我上面概述的内容接近“正式”路线,但在我看来,这无异于描述使用巧克力防火剂的最佳做法。