关于这个问题,VUE官网上说的很清楚
image.png
<template>
<view>
<view v-for="(item,index) of arr">
<view @click="edit_arr(index)">点击:{{item}}</view>
</view>
<br/><br/><hr/><br/><br/>
num:{{num}}
<view v-for="(item,index) of obj">
<view @click="edit_obj(index)">点击:{{index}}__{{item}}</view>
</view>
<br/><br/><hr/><br/><br/>
<view v-for="(item,index) of obj2">
<view @click="edit_obj2(index)">点击:{{index}}__{{item}}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
num:0,
arr:[1,3,5],
obj:{
a:2,
b:4,
c:6,
d:8
},
obj2:[{
name:'a',
value:'1'
},{
name:'b',
value:'2'
},{
name:'c',
value:'3'
}]
}
},
onLoad() {
},
methods: {
edit_arr(index){
if(index==0){
console.log('js不能检测到数组的更改')
this.arr[index]=88
console.log(this.arr) //失败; 打印是对的,但视图并不会改变
}
if(index==1){
//由于监听到arr[1]的改变,触发了页面数据更新,所以arr[0]也更新了
console.log('set方式可以检测到数组的更改')
this.$set(this.arr,index,88) //方式1
}
if(index==2){
console.log('splice方式可以检测到数组的更改')
this.arr.splice(index,1,88); //方式2
}
},
edit_obj(index){
if(index=='a'){
console.log('js能检测到对象原有元素的更改')
this.obj[index]+=1
}
if(index=='b'){
console.log('js不能检测到对象的新增')
this.obj['e']=1
}
if(index=='c'){
console.log("由于监听到obj['c']的改变,触发了页面数据更新,所以obj['e']也更新了")
this.obj[index]+=1
}
if(index=='d'){
console.log("由于监听到num的改变,触发了页面数据更新,所以obj['f']也更新了")
this.num+=1
this.obj['f']=1
}
if(index=='e'){
console.log('js不能检测到对象新增元素的更改')
this.obj[index]+=1
}
if(index=='f'){
console.log('不能检测到新增元素的更改,但由于监听到num的改变,触发了页面数据更新')
this.obj[index]+=1
this.num+=1
}
},
edit_obj2(index){
if(index==0){
console.log('js能检测到对象的更改')
this.obj2[index].value=11 //正确的,因为js能检测到对象的更改
this.$set(this.obj2[1],'value',22) //这样写也可以,只是多余了
}
if(index==1){
console.log('js不能检测到对象的新增')
this.obj2[3]={name:'d',value:33} //失败; 打印是对的,但视图并不会改变
}
if(index==2){
console.log('由于监听到obj2[2]的改变,触发了页面数据更新,所以obj2[3]新增了')
this.obj2[index].value=44
this.obj2[3]={name:'d',value:55}
}
if(index==3){
console.log('js不能检测到对象新增元素的更改')
this.obj2[index].value=66
}
}
}
}
</script>
vue实现双向数据绑定的机制是数据劫持,也就是在所有对象上有个Object.defineProperty()方法,通过监听set,get方法去实现,而数组没有这两个方法,所以就不会更新view;解决方案就是,需要我们主动通知vue;
网友评论