我具有以下vuex状态的初始结构(在VueJS项目中):
state: {
level1prop: null
}
然后我对其进行动态更改,并将其变异为以下结构:
state: {
level1prop: {
level2prop: {
level3prop: {
"customKey1": { /* this is some object 1 */ },
"customKey2": { /* this is some object 2 */ },
...
}
}
}
}
然后,我将在"customKeyN": { /* this is some object N */ }
下添加level3prop
,对我来说重要的是每次更改都会触发观察者,监视者正在监视level1prop
从{状态。
最初,在我的变异中,我通过以下方式进行此更新:
if (!state.hasOwnProperty("level1prop"))
state["level1prop"] = {};
else if (state["level1prop"] === null || state["level1prop"] === undefined)
state["level1prop"] = {};
if (!state["level1prop"].hasOwnProperty("level2prop"))
state["level1prop"]["level2prop"] = {};
else if (state["level1prop"]["level2prop"] === null || state["level1prop"]["level2prop"] === undefined)
state["level1prop"]["level2prop"] = {};
if (!state["level1prop"]["level2prop"].hasOwnProperty("level3prop"))
state["level1prop"]["level2prop"]["level3prop"] = {};
else if (state["level1prop"]["level2prop"]["level3prop"] === null || state["level1prop"]["level2prop"]["level3prop"] === undefined)
state["level1prop"]["level2prop"]["level3prop"] = {};
let payloadObj = { "customKey1": { /* this is some object 1 */ } };
state["level1prop"]["level2prop"]["level3prop"] = payloadObj;
这正在按照我想要的方式创建结构,但是不会触发更改观察者。遵循here的建议,我将代码重构为几种不同的方式,但是没有一种触发更改。这是我尝试过的最新选项的示例:
if (!state.hasOwnProperty("level1prop"))
state = Object.assign(state, { "level1prop" : {} });
else if (state["level1prop"] === null || state["level1prop"] === undefined)
state = Object.assign(state, { "level1prop" : {} });
if (!state["level1prop"].hasOwnProperty("level2prop"))
state["level1prop"] = Object.assign(state["level1prop"], { "level2prop" : {} });
else if (state["level1prop"]["level2prop"] === null || state["level1prop"]["level2prop"] === undefined)
state["level1prop"] = Object.assign(state["level1prop"], { "level2prop" : {} });
if (!state["level1prop"]["level2prop"].hasOwnProperty("level3prop"))
state["level1prop"]["level2prop"] = Object.assign(state["level1prop"]["level2prop"], { "level3prop" : {} });
else if (state["level1prop"]["level2prop"]["level3prop"] === null || state["level1prop"]["level2prop"]["level3prop"] === undefined)
state["level1prop"]["level2prop"] = Object.assign(state["level1prop"]["level2prop"], { "level3prop" : {} });
let payloadObj = { "customKey 1": { /* this is some object 1 */ } };
state["level1prop"]["level2prop"]["level3prop"] = Object.assign(state["level1prop"]["level2prop"]["level3prop"], payloadObj);
同样,这正在创建我需要的结构,但观察者仍未触发。我尝试过但未触发更改的其他一些选项是:
...
state["level1prop"]["level2prop"]["level3prop"] = Object.assign({}, state["level1prop"]["level2prop"]["level3prop"], payloadObj);
...
和
...
Object.assign(state["level1prop"]["level2prop"]["level3prop"], payloadObj);
...
在如此复杂的对象状态下,嵌套级别如此之多,有什么方法可以触发观察者进行更改吗?
答案 0 :(得分:0)
如文档Object Change Detection Caveats部分所述,您最好使用专门设计的Vue设置器Vue.set
来在以后的状态中添加子级别。
然后确保您的观察者指定了deep
选项,以便您的子级别更改时可以正确触发该选项。
const store = new Vuex.Store({
state: {
level1prop: null,
},
});
const state = store.state;
if (!state["level1prop"])
Vue.set(state, "level1prop", {})
if (!state["level1prop"]["level2prop"])
Vue.set(state["level1prop"], "level2prop", {})
if (!state["level1prop"]["level2prop"]["level3prop"])
Vue.set(state["level1prop"]["level2prop"], "level3prop", {})
let payloadObj = {
"customKey1": {
hello: "world",
},
};
state["level1prop"]["level2prop"]["level3prop"] = payloadObj;
setTimeout(() => {
// Change an already existing key.
state["level1prop"]["level2prop"]["level3prop"].customKey1.hello = "too";
}, 1000);
setTimeout(() => {
// To add or remove keys, make sure to use again Vue.set or Vue.delete.
state["level1prop"]["level2prop"]["level3prop"].customKey1.hello = "too";
Vue.set(state["level1prop"]["level2prop"], "level3propSibling", {
hi: "again",
});
}, 2000);
new Vue({
store: store,
watch: {
"$store.state": {
// Make sure you specify the `deep` option
deep: true,
handler() {
console.log(store.state);
},
},
},
});
<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/vuex@3"></script>