gpt4 book ai didi

javascript - 为什么 VueJS 检测到这个属性被添加到数组中的对象?

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

在下面的代码片段中,我有两个 Vue 组件,每个组件都有一个包含两个对象的 items 数组。如果对象的 show 属性为真,则每个组件的模板都设置为显示 items 数组的对象。数组中的第一个对象最初的 show 值为 true。第二个对象没有设置 show 值。

new Vue({
el: '#ex1',
data: () => ({ items: [{name: 'apple', show: true}, {name: 'banana'}] }),
mounted() {
// 2nd item's show property setting is not detected here
this.items[1].show = true;
}
})

new Vue({
el: '#ex2',
data: () => ({ items: [{name: 'apple', show: true}, {name: 'banana'}] }),
mounted() {
// 2nd item's show property setting IS detected...
this.items[1].show = true;

// ...when the 1st item's show property is set to false
this.items[0].show = false;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="ex1">
Example 1:
<div v-if="items[0].show">{{ items[0] }}</div>
<div v-if="items[1].show">{{ items[1] }}</div>
</div>

<div id="ex2">
Example 2:
<div v-if="items[0].show">{{ items[0] }}</div>
<div v-if="items[1].show">{{ items[1] }}</div>
</div>

在第一个示例中,我将 items 数组中第二个对象的 show 属性设置为 true。 Vue 未检测到模板中的更改,这是预期的。

在第二个示例中,我将第二个对象的 show 属性设置为 true,然后设置第一个对象的 show 属性对象为 false。在这种情况下,Vue 确实检测到 items 数组的两个元素的变化并相应地更新模板。考虑到 Vue 的 Change Detection Caveats,我不希望出现这种情况。 .

这似乎是一个非常无害的错误(如果它甚至有资格作为错误的话),所以我不确定它是否值得报告。但是,我想知道是否有人能够解释这种行为。为什么 Vue 检测到第二个例子中对象添加了 show 属性?

最佳答案

更改reactive 属性(第一个对象的show)会触发重新渲染。 Vue 忠实地呈现模板引用的对象的当前状态,其中包括第二个对象。

第二个对象的 show 属性仍然不是响应式的,对它的更改不会更新 Vue。这只是触发更新的第一个对象上响应式属性状态的更改。

换句话说,改变第二个对象的 show 属性,因为它是在事实之后添加的,永远不会更新 Vue,但是改变第一个对象的 show 属性总是会更新,更新只会渲染数组的当前状态,无论它是如何添加的。

我不会认为这是一个错误。

查看差异的一种简单方法是在更新后将数组记录到控制台。您会看到第二个对象的 show 属性未被观察到,但仍然存在。

编辑我想根据评论稍微澄清一下。之所以在Vue中出现第二个对象的变化,是因为整个Vue重新渲染,在Vue中直接引用了第二个对象。例如,如果您将值向下传递给组件,则不会重新呈现第二个对象。

这是一个示例,显示当值传递给组件时第二个对象永远不会更新(因为组件管理渲染)。

console.clear()

Vue.component("item", {
props: ["item"],
template: `
<div>Item Show: {{item.show}}</div>
`
})

new Vue({
el: '#ex2',
data: () => ({ items: [{name: 'apple', show: true}, {name: 'banana'}] }),
mounted() {
// 2nd item's show property setting IS detected...
this.items[1].show = true;

// ...when the 1st item's show property is set to false
this.items[0].show = false;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="ex2">
This will show false, because that is the current state and this object's show
property is reactive
<item :item="items[0]"></item>
<hr>
This will not show *anything*, despite the current state of show=true
because the object's show property is not reactive
<item :item="items[1]"></item>
</div>

关于javascript - 为什么 VueJS 检测到这个属性被添加到数组中的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48811472/

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