在Vuex中,同时拥有“动作”和“突变”的逻辑是什么?
我理解组件不能修改状态的逻辑(这看起来很聪明),但同时拥有动作和突变似乎是在编写一个函数来触发另一个函数,然后再改变状态。
“动作”和“突变”之间的区别是什么,它们是如何一起工作的,更重要的是,我很好奇Vuex开发人员为什么决定这样做?
在Vuex中,同时拥有“动作”和“突变”的逻辑是什么?
我理解组件不能修改状态的逻辑(这看起来很聪明),但同时拥有动作和突变似乎是在编写一个函数来触发另一个函数,然后再改变状态。
“动作”和“突变”之间的区别是什么,它们是如何一起工作的,更重要的是,我很好奇Vuex开发人员为什么决定这样做?
当前回答
这似乎没有必要有一个额外的操作层来调用突变,例如:
const actions = {
logout: ({ commit }) => {
commit("setToken", null);
}
};
const mutations = {
setToken: (state, token) => {
state.token = token;
}
};
因此,如果调用actions调用注销,为什么不调用突变本身呢?
动作的整个思想是从一个动作内部调用多个突变,或者发出Ajax请求或任何你能想到的异步逻辑。
我们最终可能会有发出多个网络请求的动作,并最终调用许多不同的突变。
因此,我们尝试将尽可能多的复杂性从我们的Vuex.Store()中添加到我们的动作中,这使得我们的突变、状态和getter更干净、更直接,并与使Vue和React等库流行的模块化保持一致。
其他回答
问题1:Vuejs的开发者为什么决定这样做?
答:
当您的应用程序变得很大,并且有多个开发人员在这个项目上工作时,您会发现“状态管理”(特别是“全局状态”)变得越来越复杂。 Vuex方式(就像react.js中的Redux一样)提供了一种新的机制来管理状态、保持状态和“保存和跟踪”(这意味着每个修改状态的操作都可以被调试工具vue-devtools跟踪)
问题2:“action”和“mutation”有什么区别?
让我们先看看官方的解释:
Mutations: Vuex mutations are essentially events: each mutation has a name and a handler. import Vuex from 'vuex' const store = new Vuex.Store({ state: { count: 1 }, mutations: { INCREMENT (state) { // mutate state state.count++ } } }) Actions: Actions are just functions that dispatch mutations. // the simplest action function increment ({commit}) { commit('INCREMENT') } // a action with additional arguments // with ES2015 argument destructuring function incrementBy ({ dispatch }, amount) { dispatch('INCREMENT', amount) }
以下是我对上述问题的解释:
突变是改变状态的唯一方法 突变并不关心业务逻辑,它只关心“状态” 操作是业务逻辑 动作一次可以提交多个突变,它只实现业务逻辑,不关心数据更改(由突变管理)
突变是同步的,而操作可以是异步的。
换句话说:如果您的操作是同步的,则不需要操作,否则就实现它们。
免责声明-我只是刚刚开始使用vuejs,所以这只是我推断的设计意图。
时间机器调试使用状态的快照,并显示动作和变化的时间轴。理论上,我们可以在记录状态设置器和获取器的同时进行操作,以同步地描述突变。但之后:
We would have impure inputs (async results) which caused the setters and getters. This would be hard to follow logically and different async setters and getters may surprisingly interact. That can still happen with mutations transactions but then we can say the transaction needs to be improved as opposed to it being a race condition in the actions. Anonymous mutations inside an action could more easily resurface these kinds of bugs because async programming is fragile and difficult. The transaction log would be hard to read because there would be no name for the state changes. It would be much more code-like and less English, missing the logical groupings of mutations. It might be trickier and less performant to instrument recording any mutation on a data object, as opposed to now where there are synchronously defined diff points - before and after mutation function call. I'm not sure how big of a problem that is.
将下面的事务日志与命名的突变进行比较。
Action: FetchNewsStories
Mutation: SetFetchingNewsStories
Action: FetchNewsStories [continuation]
Mutation: DoneFetchingNewsStories([...])
使用没有命名突变的事务日志:
Action: FetchNewsStories
Mutation: state.isFetching = true;
Action: FetchNewsStories [continuation]
Mutation: state.isFetching = false;
Mutation: state.listOfStories = [...]
我希望您能从这个例子中推断出动作中的异步和匿名突变可能增加的复杂性。
https://vuex.vuejs.org/en/mutations.html
Now imagine we are debugging the app and looking at the devtool's mutation logs. For every mutation logged, the devtool will need to capture a "before" and "after" snapshots of the state. However, the asynchronous callback inside the example mutation above makes that impossible: the callback is not called yet when the mutation is committed, and there's no way for the devtool to know when the callback will actually be called - any state mutation performed in the callback is essentially un-trackable!
因为没有突变就没有状态!提交时——执行以可预见的方式改变状态的一段逻辑。突变是设置或改变状态的唯一方法(所以没有直接的变化!),而且它们必须是同步的。这个解决方案驱动了一个非常重要的功能:突变将登录到devtools。这为您提供了良好的可读性和可预测性!
还有一件事——行动。正如我们所说的,行为会导致突变。所以它们不会改变存储,也不需要这些是同步的。但是,他们可以管理一个额外的异步逻辑!
这似乎没有必要有一个额外的操作层来调用突变,例如:
const actions = {
logout: ({ commit }) => {
commit("setToken", null);
}
};
const mutations = {
setToken: (state, token) => {
state.token = token;
}
};
因此,如果调用actions调用注销,为什么不调用突变本身呢?
动作的整个思想是从一个动作内部调用多个突变,或者发出Ajax请求或任何你能想到的异步逻辑。
我们最终可能会有发出多个网络请求的动作,并最终调用许多不同的突变。
因此,我们尝试将尽可能多的复杂性从我们的Vuex.Store()中添加到我们的动作中,这使得我们的突变、状态和getter更干净、更直接,并与使Vue和React等库流行的模块化保持一致。