gpt4 book ai didi

javascript - Vuex:无法更改 Action 中深度嵌套的状态数据

转载 作者:搜寻专家 更新时间:2023-10-30 22:25:54 26 4
gpt4 key购买 nike

在商店里,我有一个 Action 来更新一些数据, Action 看起来像这样:


setRoomImage({ state }, { room, index, subIndex, image }) {
state.fullReport.rooms[room].items[index].items[subIndex].image = image;
console.log(state.fullReport.rooms[room].items[index].items[subIndex])
},

因为所有这些数据都是动态的,所以我必须动态更改嵌套值并且不能直接对属性进行硬编码。数据如下所示:

fullreport: {
rooms: {
abc: {
items: [
{
type: "image-only",
items: [
{
label: "Main Image 1",
image: ""
},
{
label: "Main Image 2",
image: ""
}
]
}
]
}
}
}

当我发送操作时,在控制台中我可以看到子属性 image 的值已成功改变,但是如果我从 Chrome 中的 Vue DevTools 访问 VueX 商店,我看到那里的值(value)没有改变。这是控制台输出:

enter image description here

拜托,有人能告诉我为什么会这样吗?据我所知,数据正在成功更改,但不知何故状态没有显示它,因此我的组件不会重新呈现。

我也试过使用 Vue.set 而不是简单的赋值,但还是不行 :(

Vue.set(
state.fullReport.rooms[room].items[index].items[subIndex],
"image",
image
);

编辑:

根据 David Gard 的 回答,我尝试了以下操作:

我也在使用 Lodash _(我知道制作对象的完整副本并不好),这是变异代码块。

let fullReportCopy = _.cloneDeep(state.fullReport);
fullReportCopy.rooms[room].items[index].items[subIndex].image = image;
Vue.set(state, "fullReport", fullReportCopy);

现在在计算属性中,state.fullReport 是一个依赖项,我有一个 console.log,只要计算属性重新出现,它就会打印出一个字符串- 计算。

每次我提交这个突变时,我都会看到计算属性记录字符串,但它接收的状态仍然没有改变,我猜 Vue.set 只是告诉计算属性状态改变了,但实际上并没有改变它。因此,我的组件的 UI 没有变化。

最佳答案

如评论中所述 - 如果您在商店中持有深层嵌套状态,它很快就会变得复杂。

问题是,您必须以两种不同的方式填充数组和对象,因此,请考虑您是否需要访问它们的本地方法。不幸的是,Vuex 还不支持响应式(Reactive) map 。

除此之外,我还处理需要动态设置具有多个嵌套级别的属性的项目。一种解决方法是递归设置每个属性。

它不漂亮,但它有效:

function createReactiveNestedObject(rootProp, object) {
// root is your rootProperty; e.g. state.fullReport
// object is the entire nested object you want to set

let root = rootProp;
const isArray = root instanceof Array;
// you need to fill Arrays with native Array methods (.push())
// and Object with Vue.set()

Object.keys(object).forEach((key, i) => {
if (object[key] instanceof Array) {
createReactiveArray(isArray, root, key, object[key])
} else if (object[key] instanceof Object) {
createReactiveObject(isArray, root, key, object[key]);
} else {
setReactiveValue(isArray, root, key, object[key])
}
})
}

function createReactiveArray(isArray, root, key, values) {
if (isArray) {
root.push([]);
} else {
Vue.set(root, key, []);
}
fillArray(root[key], values)
}

function fillArray(rootArray, arrayElements) {
arrayElements.forEach((element, i) => {
if (element instanceof Array) {
rootArray.push([])
} else if (element instanceof Object) {
rootArray.push({});
} else {
rootArray.push(element);
}
createReactiveNestedFilterObject(rootArray[i], element);
})
}

function createReactiveObject(isArray, obj, key, values) {
if (isArray) {
obj.push({});
} else {
Vue.set(obj, key, {});
}
createReactiveNestedFilterObject(obj[key], values);
}

function setValue(isArray, obj, key, value) {
if (isArray) {
obj.push(value);
} else {
Vue.set(obj, key, value);
}
}

如果有人有更聪明的方法来做到这一点,我非常想听听!

编辑:

我使用上面发布的解决方案的方式是这样的:

// in store/actions.js

export const actions = {
...
async prepareReactiveObject({ commit }, rawObject) {
commit('CREATE_REACTIVE_OBJECT', rawObject);
},
...
}

// in store/mutations.js
import { helper } from './helpers';

export const mutations = {
...
CREATE_REACTIVE_OBJECT(state, rawObject) {
helper.createReactiveNestedObject(state.rootProperty, rawObject);
},
...
}

// in store/helper.js

// the above functions and

export const helper = {
createReactiveNestedObject
}

关于javascript - Vuex:无法更改 Action 中深度嵌套的状态数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57907075/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com