赞
踩
前言
Vue中的数据监听离不开Object.defineProperty()方法的使用,在了解数据监测原理之前,建议先掌握defineProperty的用法。
目标
1 数据监测问题
2 数据监测原理
3 如何实现数组更新
<button @click="updatePeople">更新一个用户信息</button>
<ul>
<li v-for="(item,index) in people" :key="index">
{{item.name}}----{{item.age}}
</li>
</ul>
// 可以实时更新
updatePeople(){
console.log('更新用户信息')
this.people[0].name = '马冬梅'
this.people[0].age = '40'
},
updatePeople(){
console.log('更新用户信息')
// 实时更新页面失败
this.people[0] = {name:'马冬梅',age:40}
},
vue中的数据更新主要通过Object.defineProperty()中的set来实现的,people数组下的对象没有get与set,而对象中的name、age有set,所以在设置name、age值时会同步的进行更新
现有一个需求:在页面渲染完成后,动态的给对象添加属性,并打印属性与属性值。
看似很好实现的一个需求,但是当我们的动态的添加属性后,也页面却无任何更新,这是为什么呢?
给data中的属性绑定get、set是在new Vue()的过程中进行绑定的
,但是动态添加属性是在绑定之后,也就是后来添加的属性无set,修改值就无法试试的去监测数据更新了。
为了解决此问题,Vue提供了Vue.set方法,用于添加响应式的property
Vue.set() 与 vm.$set()时一样的效果
Vue.set(vm.pseron,'sex','男生') === vm. $set(vm.pseron,'sex','男生')
Vue.set()也不是任何情况下都可以使用的,若作用的对象是Vue实例或者实例的根数组对象,会无效
data:{
pserson: {
name: "李四",
age: 32,
children: {
name: "王五",
age: 6,
},
}
}
<ul>
<li v-for="(value,key,index) of pserson" :key="index">
{{key}}----------{{value}}
</li>
</ul>
在讨论如何解决数组更新问题之前,先来看一下对象是如何实现实时更新的。
详细的就不再描述了,不了解的可以去看看vue 【vue中的数据代理】
对象代理流程大致是:
简单写个例子来模拟一下Vue中对象的数据监听。Vue中对象的数据监听用的也是Object.defineProperty,通过递归遍历对象,确保对象中的每个属性值都有get与set
<script type="text/javascript"> let data = { name: '张三', age: '18' } const obs = new Observer(data) let vm = {} vm._data = data = obs function Observer(obj) { const keys = Object.keys(obj) keys.forEach(key => { Object.defineProperty(this, key, { get() { return obj[key] }, set(val) { obj[key] = val } }) }); } </script>
现有一个需求:在页面渲染完成后,动态的给对象添加属性,并打印属性与属性值。
看似很好实现的一个需求,但是当我们的动态的添加属性后,也页面却无任何更新,这是为什么呢?
给data中的属性绑定get、set是在new Vue()的过程中进行绑定的
,但是动态添加属性是在绑定之后,也就是后来添加的属性无set,修改值就无法试试的去监测数据更新了。
data:{
pserson: {
name: "李四",
age: 32,
children: {
name: "王五",
age: 6,
},
}
}
<ul>
<li v-for="(value,key,index) of pserson" :key="index">
{{key}}----------{{value}}
</li>
</ul>
当数组中对象的属性发生变化时,属性可以实时的监听。但是我们整个改变数组的中的值时,页面却没有实时更新。
我们用数组方法往数组中添加对象,这个对象中的属性也是响应式的
属性也是响应式
的Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添属性!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。