这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战
前言
各位掘友们晚上好,一周辛劳的工作结束,迎来了幸福的周末时光,大家周末嗨皮呀!好了,闲言少叙,一起来今天的内容- 今天来介绍下Vue2的响应式原理。
vue2的响应式原理
大家知道,vue2的响应式原理是用到了数据劫持,语法是Object.defineProperty(),这个是ES5的语法,作用就是劫持对象的某个属性,比如下面对象obj, Object.defineProperty()想要劫持这个对象,只需要把obj放在这个方法里即可,如:
<script>
var obj = {
name: 'loncon',
age: 18
}
Object.defineProperty(obj, 'name' ,{
get() {
console.log(obj,'劫持了obj的name属性');
},
set() {
}
})
//参数一: 对象
//参数二: 属性
//参数三: 选项
</script>
在控制台输入obj.name,打印的结果如下:
如上图,name 属性被劫持了,打印处理的结果展开就是undefined,但是我们肯定要用这个属性,是所以要return出劫持的对象的内容。
get() {
console.log(obj,'劫持了obj的name属性');
return obj.name
},
可是这样做是不对的,因为return出的name继续被劫持,依次进行,就会递归,进入死循环。
如何处理
劫持之前把值存起来
<script>
var obj = {
name: 'loncon',
age: 18
}
var name = obj.name
Object.defineProperty(obj, 'name' ,{
get() {
console.log(obj,'劫持了obj的name属性');
return name
},
set() {
}
})
</script>
这样就可以拿到劫持的name属性值:
如何设置属性
利用set,就可以设置,不仅会改属性值,还可以更新dom,因为你是设置属性值,就不会走get函数了。
set(value) {
console.log('set函数执行了');
name = value
}
vue内部如何操作
vue就是利用set函数,会把obj中所有的数据都进行劫持,然后更改就会改变属性的值。源码分析如下:
<script>
var obj = {
name: 'loncon',
age: 18
}
for(var k in obj) {
var item = obj[k]
Object.defineProperty(obj, k ,{
get() {
console.log(obj,'劫持了obj的name属性');
return name
},
// 只要设置name属性, obj.name = '设置值'
set(value) {
console.log('DOM更新');
item = value
}
})
}
</script>
Object.defineProperty()语法的缺陷:
- 一次只能劫持一个属性,因为不是劫持对象,所以如果对象有很多属性,需要一个个的劫持。 2.如果对象新增一个属性,那这个属性不是响应式的 比如:
这个新增的属性,没有打印DOM更新,说明这个属性没有被劫持到。
缺陷3: 天生劫持不了数据的下标和长度
后记
好了,小伙伴们,今天的分享就到这里了,下次我们用案例来讲vue2中响应式原理的缺陷及vue3的响应式原理,再会~