一、Vue更新数据存在的问题
示例代码如下:
<div id="app">
<h2>人员信息</h2>
<button @click="update">点击更新Robert人员信息</button>
<ul>
<li v-for="(p,index) of perArr" :key="p.id">
{{p}}
</li>
</ul>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data: {
perArr: [{id: '001', name: 'Robert', age: 19},
{id: '002',name: 'Rose', age: 18},
{id: '003', name: 'Jack', age: 20}]
},
methods:{
update(){
this.perArr[0].name ='Robin'
this.perArr[0].age =20
}
}
})
</script>
效果如下: 我们通过替换数组元素的方式能够成功修改人员数据,页面也能够成功显示最新数据;而通过修改数组数据我们可以发现页面无法正常显示最新数据,在Vue 工具中也无法看到最新的数据,而我们在控制台中打印vm 对象数据可以看到最新的数据,这是什么原因呢?
点开vm 对象的详细数据,我们可以发现第一个数据数据中数据代理生成的get 、set 方法被破坏了,导致页面无法响应式的显示。
二、Vue监测数据改变的原理
示例代码如下:
<body>
<div id="app">
<button @click="addSex">添加属性</button>
<ul>
<li v-for="(friend,index) of student.friends" :key="index">
{{friend}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#app',
data:{
name:'Peking',
address:'北京',
student:{
name:'tom',
parents:{
father:40,
mom:39,
},
friends:[
'Jerry','Able','Apple'
]
}
},
methods:{
addSex(){
Vue.set(this.student,'sex','男')
}
}
})
</script>
① 对象
通过打印vm 对象我们可以看到Vue 给vm 中的对象属性中的属性添加了多个get 、set 代理方法。 ② 数组
通过观察数组的代理方法我们可以看到Vue 并没有给数组里的每个元素都添加代理方法,所以说当我们只是修改数组中的某个元素时,页面不会有响应式的变化,需要使用Vue 包裹过的方法才会触发视图更新。这些被包裹过的方法包括:push() 、pop() 、shift() 、unshift() 、splice() 、sort() 、reverse() 。
三、Vue 数据监视总结
① Vue 会监视data 中所有层次的数据
② 如何监测对象中的数据?
通过setter 实现监视,且要在new Vue 时就传入要监测的数据,对象中后追加的属性,Vue 默认不做响应式处理,如需给后添加的属性做响应式,请使用如下API :
Vue.set(target,propertyName/index,value) vm.$set(target,propertyName/index,value)
③ 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
在Vue修改数组中的某个元素一定要用如下方法:push() 、pop() 、shift() 、unshift() 、splice() 、sort() 、reverse()
④ 特别注意:Vue.set() 和vm.$set() 不能给vm 或vm 的根数据对象添加属性!!!
|