前言
vue3.0国庆的时候刚发布了部分代码,之前学习过vue部分源码(都快忘完了,还是得记录,看完都会了,但是忘得比学得快多了。。。为了加深记忆和更好地理解应用,最近考虑把相关知识都写成博客)这里针对vue2.x和3.0的响应式系统的异同来进行分析记录。
一、vue2.x的响应式原理
vue是一个MVVM框架,不同于其他单向数据流,他实现了双向数据绑定,当用户数据修改,相关的页面也会同时更改,那他的原理是什么呢?
vue.$set()
这种更新方式使用了发布-订阅者模式;v-model
这种方式是通过数据劫持以及结合发布者-订阅者来实现的;
1、发布-订阅者模式
2、 数据劫持
数据劫持是利用ES5的Object.defineProperty(obj, key, val)
来劫持各个属性的的setter以及getter,在数据变动时发布消息给订阅者,从而触发相应的回调来更新视图。
2.1 理解Object.defineProperty()
2.1.1 什么是Object.defineProperty()?
MDN中对Object.defineProperty()
的定义:
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法: Object.defineProperty(obj, prop, descriptor)
- obj :要在其上定义属性的对象。
- prop:要定义或修改的属性的名称。
- descriptor:将被定义或修改的属性描述符。
2.1.2 理解descriptor属性描述符
上面三个属性应该只有descriptor
不是很好理解,举个简单的数据修改的例子:
1.descriptor
中的:数据描述符
let obj = {
name: 'JCat_李小黑'}
// 例1.修改属性,默认没有 enumerable,没有 configurable,没有 writable
Object.defineProperty(obj, "name", {
value: 'JCat'
})
console.log(obj); //{name: "JCat"}
// 例2.修改属性,真实显示
Object.defineProperty(obj, "name", {
value: 'JCat',
enumerable: false,
configurable: false,
writable: false
})
console.log(obj); //{name: "JCat"}
// 例3.添加属性
Object.defineProperty(obj, "age", {
value: 18,
enumerable: true,
configurable: true,
writable: true
})
console.log(obj); //{name: "JCat", age: 18}
上述例子是descriptor
的其类一种属性:数据描述符,其中可选有4中参数。
- value :属性的值,any类型,默认是undefined,用法:上述例1,2
- writable:属性的值是否可以重写,设置为true可以被重写;设置为false,不能被重写。默认为false。