双向绑定原理
1、vue2.x采用的是object.defineProperty
- vue2.x的双向数据绑定是通过数据劫持结合发布者订阅者模式的方式来实现的,通过object.defineProperty来劫持各个属性的setter,getter,在数据变化时发布消息给订阅者,触发相应的监听回调来渲染视图。也就是说数据和视图同步,数据发生变化,视图变化,视图变化,数据也随之发生变化。
- Obejct.defineproperty(obj,prop,descriptor)方法,接收三个参数,分别是obj(定义其上属性的对象),prop(定义或者修改的属性),description(具体的改动方法),就是用这个方法来定义一个值,当使用时我们调用他里面的get方法,当我们给这个属性赋值时,用到他的set方法。
具体步骤:
- 对需要 Observer(观察)的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter;这样的话,给对象的某个值赋值,就会触发setter,那么就可以监听到数据的变化。
- Compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定到更新函数,添加监听数据的订阅者,一旦数据发生变动,收到通知,更新视图。
- Watcher订阅者 是 Observer 和 Compile 之间的通信桥梁,主要做的事情就是:
- 在自身实例化时 往属性订阅器 (dep) 里面添加自己。
- 自身必须有个update方法。
- 待属性变动 即 dep.notice() 发布通告时,能调用自身的update方法,并触发 Compile 中绑定的回调。
- MVVM作为数据绑定的入口,整合Observer、Compile和 Watcher 三者,通过Observer 来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和 Compile 之间的通信桥梁,到达数据变化视图更新,视图变化数据更新的效果。
2、vue3.x采用的是proxy
- proxy:对象用户定义基本操作的自定义行为(比如:属性的查找,复制,函数调用等等)。proxy就像一个拦截器一样,它可以在读取对象的属性、修改对象的属性、获取对象属性列表时,阻止对象上的默认行为,然后使用我们的自定义行为,比如我们通过拦截默认的set方法,再自己定一个set方法添加回调函数。
- proxy的语法
const proxy = new Proxy(target,handler)
- target: 要兼容的对象,可以是一个对象,数组,函数等等
- handler: 是一个对象,里面包含了可以监听这个对象的行为函数,比如里面的get与set
1) handler.get
当通过proxy去读取对象里面的属性的时候,会进入到get钩子函数里面
2) handler.set
当通过proxy去为对象设置修改属性的时候,会进入到set钩子函数里面
3) handler.deleteProperty
当使用delete去删除对象里面的属性的时候,会进入deleteProperty`钩子函数
4) handler.apply
当proxy监听的是一个函数的时候,当调用这个函数时,会进入apply钩子函数
5) handle.ownKeys
当通过Object.getOwnPropertyNames, Object.getownPropertySymbols, Object.keys, Reflect.ownKeys去获取对象的信息的时候,就会进入ownKeys这个钩子函数
6) handler.construct
当使用new操作符的时候,会进入construct这个钩子函数
详细介绍
get
handle.get(target,key, receiver)
当通过 proxy 去读取对象里面的属性的时候,会进入到get钩子函数里面
target: 目标对象,即通过proxy代理的对象
key: 要访问的属性名称
receiver: receiver相当于是我们要读取的属性的this,一般情况下他就是proxy对象本身
set
handle.set(target,key,value, receiver)
当为对象里面的属性赋值的时候,会触发set
target: 目标对象,即通过proxy代理的对象
key: 要赋值的属性名称
value: 目标属性要赋的新值
receiver: 与 get的receiver 基本一致