https://vuex.vuejs.org/en/getting-started.html上的文档 说,
你不能直接改变商店的状态.改变商店状态的唯一方法是明确提交突变.
我的问题是,这是一个好的做法,还是Vuex国家内部的工作方式?换句话说,Vuex状态是否以与Vue数据相同的方式反应(它将js对象转换为可观察的对象),还是其他东西?
一个类似的问题 - 您是否可以直接更改操作中的状态而不是创建突变?我知道这是不好的做法,它失去了遵循惯例的一些可追溯性 - 但它有效吗?
acd*_*ior 14
你可以直接改变动作中的状态而不是创建变异吗?我知道这是不好的做法,它失去了遵循惯例的一些可追溯性 - 但它有效吗?
工作,但会发出警告和错误.
vue.js:584 [Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] Do not mutate vuex store state outside mutation handlers."
(found in <Component>)
warn @ vue.js:584
...
vue.js:1719 Error: [vuex] Do not mutate vuex store state outside mutation handlers.
at assert (VM260 vuex.js:103)
Run Code Online (Sandbox Code Playgroud)
谁知道在此之后还有什么可能被打破.
亲眼看看(注意模板中的数据更新):
const store = new Vuex.Store({
strict: true,
state: {
people: []
},
mutations: {
populate: function (state, data) {
//Vue.set(state, 'people', data);
}
}
});
new Vue({
store,
el: '#app',
mounted: function() {
let self = this;
this.$http.get('https://api.myjson.com/bins/g07qh').then(function (response) {
// setting without commit
Vue.set(self.$store.state, 'people', response.data);
//self.$store.commit('populate', response.data)
}).catch(function (error) {
console.dir(error);
});
},
computed: {
datadata: function() {
return this.$store.state.people
}
},
})Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/vue-resource"></script>
<div id="app">
Data: {{ datadata }}
</div>Run Code Online (Sandbox Code Playgroud)
Vuex状态以与Vue数据相同的方式反应(它将js对象转换为可观察的对象),还是其他东西?
是.实际上,这是Vue本身使商店对象反应.来自Mutations官方文档:
突变遵循Vue的反应性规则
由于Vuex存储的状态由Vue激活,当我们改变状态时,观察状态的Vue组件将自动更新.这也意味着当使用普通Vue时,Vuex突变会受到相同的反应性警告:
首先要预先初始化商店的所有需要字段的初始状态.
向Object添加新属性时,您应该:
使用
Vue.set(obj, 'newProp', 123),或用新的替换该Object.例如,使用stage-3 对象扩展语法,我们可以这样写:
Run Code Online (Sandbox Code Playgroud)state.obj = { ...state.obj, newProp: 123 }
因此,即使在突变代码中,如果您覆盖observable或直接创建新属性(通过不调用Vue.set(obj, 'newProp', newValue)),该对象也不会被动反应.
因此,可观察对象似乎与常规Vue数据略有不同 - 只允许从变异处理程序进行更改.是对的吗?
他们可能,但我不相信他们.文档和证据(见下面的vm.$watch讨论)指出它们与data对象完全相同,至少在反应/可观察行为方面.
对象"如何知道"它是如何从不同的上下文中变异的?
这是一个很好的问题.请允许我改写一下:
如果
Vue.set(object, 'prop', data);从Vue内部调用会引发异常(参见上面的演示),为什么Vue.set(object, 'prop', data);在变异函数内调用不会?
答案就在于内部Store.commit()的代码.它通过_withCommit()内部函数执行变异代码.
所有这_withCommit()确实是它设置一个标志this._committing,以true和则(并返回执行突变代码 _committing到false的exection后).
然后Vuex商店正在观察各州的变量,如果它通知(也就是观察者触发)变量在_committing标志发生变化时false发出警告.
(奖励:做注意到vuex使用vm.$watch --see Vue公司的vm.$watchAPI文档,如果你不熟悉它-观察变量,另一种暗示,即国家的目标是相同的数据对象-他们依靠Vue公司的内部.)
现在,为了证明我的观点,让我们通过设置state._committingtrue自己来"欺骗"vuex然后Vue.set()从外面调用一个mutator.如下所示,未触发任何警告.德勤.
const store = new Vuex.Store({
strict: true,
state: {
people: []
},
mutations: {
populate: function (state, data) {
//Vue.set(state, 'people', data);
}
}
});
new Vue({
store,
el: '#app',
mounted: function() {
let self = this;
this.$http.get('https://api.myjson.com/bins/g07qh').then(function (response) {
// trick the store to think we're using commit()
self.$store._committing = true;
// setting without commit
Vue.set(self.$store.state, 'people', response.data);
// no warning! yay!
}).catch(function (error) {
console.dir(error);
});
},
computed: {
datadata: function() {
return this.$store.state.people
}
},
})Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/vue-resource"></script>
<div id="app">
Data: {{ datadata }}
</div>Run Code Online (Sandbox Code Playgroud)
Ste*_*gin 10
我会让这个变得非常简单:
因为 state 对象已经是reactive,所以可以完全避免使用 getter 和 mutations。Vue 的所有模板、计算的、监视的等将继续像使用组件的数据一样工作。该商店的state行为是shared data object.
但是这样做您将失去实现时间旅行调试、撤消/重做和设置断点的能力,因为您将command design pattern通过使用方法绕过成员的封装。
https://en.m.wikipedia.org/wiki/Command_pattern
| 归档时间: |
|
| 查看次数: |
8953 次 |
| 最近记录: |