vue.js - 具有标准化数据的 Vuex getter 不是响应式的
问题描述
我已经在 Vuex 应用程序中对我的数据进行了规范化,但我无法找到有关如何查看数据以进行更改的答案。例如,这是我的设置的简化版本。
状态:
const state = {
shapes: {
collection: [1, 2, 3],
data: {
1: {
type: 'circle',
isActive: false,
},
},
}
}
吸气剂:
const getters = {
findShape: (state) => (id) => {
return state.shapes.data[id];
}
allShapes: (state, getters) => {
return state.shapes.collection.map(id => getters.findShape(id));
}
}
在我的组件中,我在计算属性中调用 allShapes getter,并通过 v-for 将形状向下传递给子组件。
computed: {
shapes() {
return this.$store.getters.allShapes;
}
}
添加和删除形状工作正常。问题是每当我更新数据对象中的属性时,更改都不会反映在我的组件中。这是我设置 isActive 属性的突变:
const mutations = {
setActive(state, shape) {
Vue.set(state.shapes.data[shape.id], 'isActive', shape.isActive);
}
}
然后引用 isActive 属性的任何组件都不会更新。我明白为什么会发生这种情况,但除了返回嵌套数组结构之外,我还没有找到解决方案。当数据对象发生变化时,有没有办法在 allShapes getter 中触发更新?或者是否有不同的方法可以将数据拉入我的组件以使其具有反应性?
解决方案
首先,关于Vue.set
.
调用Vue.set
有两件事:
- 如果该属性不存在,它会将其添加为反应性属性。
- 属性值将被更新。
这里有一个边缘案例。如果属性已经存在但不是反应性的,那么 usingVue.set
不会增加反应性。
默认情况下, 的属性state
将是反应性的,并且这种反应性将递归地应用于其中的所有对象和数组state
。但是,通常的警告适用于添加新属性。Vue 无法检测到添加新属性,因此它不会是响应式的。这是Vue.set
添加新属性的用例。
您很可能是从服务器加载数据以data
填充state
. 这是您需要使事情反应的关键点。当您来更新isActive
物业时,可能为时已晚。
您可能有一个看起来像这样的突变:
addShape (state, shape) {
state.shapes.data[shape.id] = shape
}
这是反应性下降的点,因为您要向state.shapes.data
. 结果将是shape
对象不会被反应系统处理,因此它的任何属性都不会是反应性的。
如果该isActive
属性不存在,那么您实际上可能会侥幸逃脱。在那种情况下,使用Vue.set
你会发现属性丢失并添加它,包括反应性。它实际上会做得更多。由于对象还没有反应,它将遍历整个对象并使所有属性都具有反应性。在这种情况下,唯一没有反应的是state.shapes.data
.
但是,在您的情况下,该属性isActive
似乎从一开始就存在。结果是Vue.set
更改时无济于事isActive
。相反,您首先需要在将对象添加到缓存时使用它。例如:
addShape (state, shape) {
Vue.set(state.shapes.data, shape.id, shape)
}
显然,我对您如何填充缓存做了一些假设,state.shapes.data
但即使您的代码与我描述的不完全一样,它也可能足够相似,可以应用相同的修复程序。
只要属性isActive
从一开始就存在于形状对象中,就不需要isActive
使用Vue.set
. 使用它向缓存添加形状就足够了。
推荐阅读
- sql-server - 哪个更适合托管在 Azure 上的 MSSQL,CPU 或 RAM 的成本更高?
- typescript - Ionic 4 在从 http 请求调用返回的对象键上抛出错误
- java - 我在向服务器发送凌空请求时遇到了一些错误......任何人都可以帮助我
- ios - 如何适应不同的屏幕尺寸
- sql - 无法在合并中绑定多部分标识符
- python-3.x - 没有名为“pptx”的模块
- java - 使用来自主题的消息并使用指数退避重试,直到使用 Spring-Kafka-2.3.0 及更高版本成功
- java - 使用 SAP Cloud SDK 版本 3.0 从 Java 调用 BAPI 时未指定目标主机异常
- xslt - XSL - 选择具有特定字段的特定项目并将输出限制为 3 个项目
- javascript - 使用 JavaScript 将值数组分配给空的 HTML 标记