javascript - Vue,如何处理深度嵌套对象的反应性
问题描述
我有一个我正在操作的对象,如下所示:
const posts = [
{ key1: "abc", key2: [{ innerKey1: "def", innerKey2: 123 }, { innerKey1: "def", innerKey2: 123 }] },
{ key1: "abc", key2: [{ innerKey1: "def", innerKey2: 123 }, { innerKey1: "def", innerKey2: 123 }] },
{ key1: "abc", key2: [{ innerKey1: "def", innerKey2: 123 }, { innerKey1: "def", innerKey2: 123 }] },
];
posts[0].key2[1].innerKey1 = "newVal";
Array inkey2
是一个道具,内部键预计会发生变化。我想在innerKey1
或innerKey2
改变时保持反应性。
因为 Vue 很难检测到这里讨论的数组和对象的变化,所以我们不能直接通过索引修改数组或直接通过键修改对象。
为了保持反应性,我们似乎需要一些复杂的逻辑来使用Vue.set()
set newVal
:
我的思路是这样的:
Vue.set(posts, 1, Vue.set(key2, 0, Vue.set(innerKey1, "newVal")))
这是在这里保持反应性的最佳方式,还是我缺少一些可以使这更容易的东西?
注意:我还尝试在我的子组件中使用深度观察器来观察key2
数组中发生的变化。但它似乎无法观察到这些变化。
//ChildComponent.vue
<html>
<div>
<RandomComponent v-for="thing in key2" :key... :innerKey2="thing.innerKey2">
</div>
</html>
<script>
props: {
key2: {
type: Array,
require: true,
},
},
watch: {
key2: {
immediate: true,
deep: true,
handler () {
console.log("Watcher working"); //Does not fire when parent mutates innerKeys
},
},
},
</script>
解决方案
我觉得这个问题不够明确。
- 如果您只想更新现有数组元素的属性,按索引变异应该可以正常工作,无需任何解决方法。
即这应该是反应性的
posts[0].key2[1].innerKey1 = "newVal";
- 但是,如果您尝试替换数组元素,则需要解决此处解释的 Vue 反应性问题
我认为您的情况最干净的解决方法是使用Array.splice
替换元素。(例如网络响应后)
const postId = 0 // the root element
const updatePost = { ...this.posts[postId] }
updatePost.key2[1].innerKey1 = 'newVal'
this.posts.splice(postId, 1, updatedPost);
推荐阅读
- html - 如何为“剩余天数”创建仅 CSS 的进度条?
- mysql - 数据库设计两张表 vs 联表,哪个更好
- python - Django 无法删除自定义字段类;makemigrations 抛出 AttributeError
- html - 位置:与垂直滚动相比,水平滚动的粘性行为不同?
- python - Python函数返回空数据框
- python - 返回协程管道输出的生成器
- javascript - Javascript Countdown 不在 C# Foreach 循环内迭代
- flutter - Flutter TextField 禁用边框
- date - 在 AWS 上的 python3 中将特定时间转换为 UTC
- java - 获取java中特定行值的更新时间