Vue.js 商店中复杂对象的反应性
Vue.js reactivity of complex objects in a store
我的问题
我正在尝试在商店中存储复杂项目的列表并从组件访问这些项目。我有一个 mqtt 接口,它接收这些项目的数据并更新它们在商店中的值。但是,ui 不会对更新这些项目的属性做出反应。
结构
在我的店里,我有两个突变:
state: {
itemList:{}
},
mutations: {
/// adds a new item to itemList
[ADD_ITEM](state, item) {
if (item&& !state.itemList[item.itemId])
{
Vue.set(state.itemList, item.itemId, item);
}
},
/// updates an existing item with data from payload
[SET_ITEM_STAT](state, { itemId, payload }) {
var item= state.itemList[itemId];
if (item) {
item.prop1 = payload.prop1;
item.prop2 = payload.prop2;
}
}
},
actions: {
/// is called from outside once when connection to mqtt (re-)established
initializeMqttSubscriptions({ commit, dispatch }, mqtt){
mqtt.subscribeItem("items/stat", async function(itemId, topic, payload) {
commit(SET_ITEM_STAT, { itemId, payload });
});
},
...
}
我也试过:
- 使用
Vue.set(state.itemList, itemId, item);
设置项目属性
- 使用
Vue.set(state.itemList[itemId], 'prop1', payload.prop1);
设置项目属性
我还想展示我如何构建ui访问和显示这些项目的组件 (Item.vue
)。它是一个组件,通过 itemId
通过路由参数显示。我有以下计算属性:
<template>
<div class="grid-page">
<h1 class="page-title">Item- <span class="fw-semi-bold">{{ id }}</span></h1>
<div>
<Widget v-if="item">
{{ item.prop1 }}
...
...
computed: {
id(){
return this.$route.params.itemId;
},
item(){
return this.$store.state.items.itemList[this.id];
}
}
所以当路由参数itemId
改变时,我成功地看到了项目数据,一切都很好。但是,如果我使用上面显示的突变更新项目的属性,则不会触发视图中的更新。
如果有人能给我提示我在这里做错了什么,我将非常高兴。提前致谢!
由于我无法发表评论要求澄清,
如果您的项目列表是嵌套对象,请尝试使用 Object.assign
[SET_ITEM_STAT](state, { itemId, payload }) {
var item= state.itemList[itemId];
if (item) {
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop1, {payload.prop1})
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop2, {payload.prop2})
// or
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId], {prop1: payload.prop1, prop2: payload.prop2})
}
}
告诉我进展如何
我的问题
我正在尝试在商店中存储复杂项目的列表并从组件访问这些项目。我有一个 mqtt 接口,它接收这些项目的数据并更新它们在商店中的值。但是,ui 不会对更新这些项目的属性做出反应。
结构
在我的店里,我有两个突变:
state: {
itemList:{}
},
mutations: {
/// adds a new item to itemList
[ADD_ITEM](state, item) {
if (item&& !state.itemList[item.itemId])
{
Vue.set(state.itemList, item.itemId, item);
}
},
/// updates an existing item with data from payload
[SET_ITEM_STAT](state, { itemId, payload }) {
var item= state.itemList[itemId];
if (item) {
item.prop1 = payload.prop1;
item.prop2 = payload.prop2;
}
}
},
actions: {
/// is called from outside once when connection to mqtt (re-)established
initializeMqttSubscriptions({ commit, dispatch }, mqtt){
mqtt.subscribeItem("items/stat", async function(itemId, topic, payload) {
commit(SET_ITEM_STAT, { itemId, payload });
});
},
...
}
我也试过:
- 使用
Vue.set(state.itemList, itemId, item);
设置项目属性
- 使用
Vue.set(state.itemList[itemId], 'prop1', payload.prop1);
设置项目属性
我还想展示我如何构建ui访问和显示这些项目的组件 (Item.vue
)。它是一个组件,通过 itemId
通过路由参数显示。我有以下计算属性:
<template>
<div class="grid-page">
<h1 class="page-title">Item- <span class="fw-semi-bold">{{ id }}</span></h1>
<div>
<Widget v-if="item">
{{ item.prop1 }}
...
...
computed: {
id(){
return this.$route.params.itemId;
},
item(){
return this.$store.state.items.itemList[this.id];
}
}
所以当路由参数itemId
改变时,我成功地看到了项目数据,一切都很好。但是,如果我使用上面显示的突变更新项目的属性,则不会触发视图中的更新。
如果有人能给我提示我在这里做错了什么,我将非常高兴。提前致谢!
由于我无法发表评论要求澄清,
如果您的项目列表是嵌套对象,请尝试使用 Object.assign
[SET_ITEM_STAT](state, { itemId, payload }) {
var item= state.itemList[itemId];
if (item) {
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop1, {payload.prop1})
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop2, {payload.prop2})
// or
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId], {prop1: payload.prop1, prop2: payload.prop2})
}
}
告诉我进展如何