我是从 react/redux
到 vue
的,在学习 vuex
的过程中我发现我可以直接改变状态和状态更改仍然会反射(reflect)在使用它的其他组件上。
这种行为在 Redux 中是被禁止的,如果我直接改变状态,其他组件将不会收到有关这些更改的通知,因此我们必须为此使用操作和化简器。
所有这些方法基本上都提供相同的结果。
methods: {
IncrementDirect () {
// mutates the state directly
this.$store.state.counter += 2;
},
incrementDispatch() {
// mutates the state inside actions
this.$store.dispatch("handleIncrement", 2);
},
incrementCommit() {
// mutates the state inside mutations
this.$store.commit("increment", 2);
},
},
我的问题是为什么允许这种行为,以及如果我们可以在应用程序中的任何位置改变状态,为什么我们必须使用mutations
。
最佳答案
Redux 与 Vuex 的不同之处在于状态更改不会创建新状态。 Vue 假装不变,但为了性能,实际上改变了状态并通过 react channel 跟踪突变。这是一个巧妙的技巧,但正如您所发现的,它有一些轻微的副作用。
当您直接更改状态(例如通过组件或操作)时,您没有使用这些官方突变 channel 。我已经调试了看起来像这样的代码,但后来发现了错误,因为 react 性没有完全发挥作用并且更新没有发生。
还应该提到的是,通过 Vue 开发工具调试 Vuex 非常方便,除非您使用突变,否则不会显示任何状态更改。此外,如果您有任何 Vuex 插件,除非发生突变,否则它们不会执行。
除了所有这些看起来有点模糊的技术原因之外,我觉得有必要指出这绝对不是 Flux 框架用于状态更改的方式。来自 React 世界,你知道状态变化应该在一个大循环中发生;在 Redux 中,组件调用操作,该操作调用一个 reducer 来返回一个新状态,然后应用该状态,并且应用程序将重新渲染并准备好接受组件的另一次更改。该框架强制将 UI 与状态分离(尽管我认为这不是一个好主意),并确保所有状态更改都发生在一个地方。 Vuex 突变也是如此 - 这是所有状态更改都应该发生的地方。超越当前状态(双关语不是故意的),应该注意的是,您可以在 Vue 3 中做一些非常有趣的事情。其中之一是您可以在 Vue 组件之外创建一个响应式对象,将该对象作为全局状态导入到您的组件中,然后随心所欲地改变它。 Vue 3 将使这些突变与整个应用程序保持同步,并且通过一些规划,它可以成为非常强大的 Vuex 替代品。
紧随其后,下一个 Vuex 看起来可能会放弃单独突变的概念,并且可以通过操作或其他方式直接改变所有状态。我敢打赌它将使用如上所述的 Vue 3 react 系统,结合 Vuex 对模块组织的思想来制作一个非常简单的框架。
总而言之,您的直觉对于前进的方向是正确的,但今天可能还为时过早。
关于vue.js - 不使用mutations直接改变Vuex状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68170766/