Javascript 为什么VueJS检测到此属性被添加到数组中的对象?

Javascript 为什么VueJS检测到此属性被添加到数组中的对象?,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,在下面的代码片段中,我有两个Vue组件,每个组件都有一个包含两个对象的items数组。如果对象的show属性为truthy,则每个组件的模板都会设置为显示items数组的对象。数组中的第一个对象最初的show值为true。第二个对象没有设置show值 newvue({ el:“#ex1”, 数据:()=>({items:[{name:'apple',show:true},{name:'banana'}]}), 安装的(){ //此处未检测到第二项的“显示”属性设置 this.items[1]。

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

newvue({
el:“#ex1”,
数据:()=>({items:[{name:'apple',show:true},{name:'banana'}]}),
安装的(){
//此处未检测到第二项的“显示”属性设置
this.items[1]。show=true;
}
})
新Vue({
el:“#ex2”,
数据:()=>({items:[{name:'apple',show:true},{name:'banana'}]}),
安装的(){
//检测到第二项的显示属性设置。。。
this.items[1]。show=true;
//…当第一项的show属性设置为false时
此.items[0].show=false;
}
})

例1:
{{items[0]}
{{items[1]}
例2:
{{items[0]}
{{items[1]}

如您发布的链接所述:

Vue不允许向已创建的实例动态添加新的根级别被动属性。但是,可以使用
Vue.set(对象、键、值)

要解决此问题,而不是。项[1]。show=true您可以编写:

Vue.set(this.items[1], 'show', true)
希望很清楚,更改第一个对象的反应属性(
show
)会触发重新渲染。Vue忠实地呈现模板引用的对象(包括第二个对象)的当前状态

第二个对象的show属性仍然不是被动的,对其所做的更改不会更新Vue。触发更新的只是第一个对象上的被动属性状态的更改

换句话说,更改第二个对象的“显示”属性(因为它是在事实之后添加的)将永远不会更新Vue,但更改第一个对象的“显示”属性将始终更新,并且无论数组是如何添加的,更新只会呈现数组的当前状态

我不认为这是个错误。

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

编辑 我想根据评论稍微澄清一下。对第二个对象的更改出现在Vue中的原因是,整个Vue将重新渲染,并且第二个对象将直接在Vue中引用。例如,如果将值传递给组件,则第二个对象将不会重新渲染

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

console.clear()
Vue.组件(“项目”{
道具:[“物品”],
模板:`
项目显示:{{Item.Show}
`
})
新Vue({
el:“#ex2”,
数据:()=>({items:[{name:'apple',show:true},{name:'banana'}]}),
安装的(){
//检测到第二项的显示属性设置。。。
this.items[1]。show=true;
//…当第一项的show属性设置为false时
此.items[0].show=false;
}
})

这将显示false,因为这是当前状态和此对象的显示
性质是反应性的

尽管当前状态为show=true,但它不会显示*任何* 因为对象的show属性不是被动的
这不是问题所在。我理解为什么我的第一个示例没有对属性添加做出反应,以及如何使用
Vue.set
来修复它。我的问题是,为什么我的第二个示例会对属性添加做出反应,即使我没有使用
Vue.set
。我也不会假设整个数组会从更新重新渲染到它的一个对象。但这种解释是有道理的@事实上,模板被触发重新渲染;因此,模板引用的所有内容都将重新呈现。我认为,如果每个对象都被传递给一个组件,那么只有具有被动属性的对象才会被重新呈现,但我必须对其进行测试。@thanksd添加了一个示例,说明了我在上述注释中的意思。