在下面的代码片段中,我有两个 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/