Object.defineProperty 的缺点及 Vue3 为什么用 Proxy
Vue 数据双向绑定的实现原理
Vue 是利用数据劫持结合发布者订阅模式实现的数据双向绑定。
observer 用来对初始化数据通过 object.defineProperty 添加 getter 和 setter,当取数据(即调用 get)的时候添加订阅对象(watcher)到数据里,当数据赋值(即调用 set)的时候就能知道数据的变化,此时调用发布订阅中心的 notify,从而遍历当前这个数据的订阅数组,执行里面所有的 watcher,通知变化 update
complier 是用来把 data 编译到 dom 中。分三步:
先把真实的 dom 移入到内存中 fragment
编译:提取想要的元素节点 v-model 和文本节点{{}}
把编译好的 fragment 塞回到页面去,第 2 步中会对编译到 dom 中的 data 添加 watcher,当 data 变化时,这里的 watcher 回调也能收到通知得到的执行
watcher 是 observer 和 compiler 之间通信的桥梁
Object.defineProperty 的缺点
无法监听数组变化,但是 vue 中是可以监听数组的变化的,那他是怎么实现的呢?使用了以下八种方法:
只能劫持对象属性,因此我们需要对每个对象的每个属性进行遍历,如果属性也是对象那么需要深度遍历,显然能劫持一个完整的对象是更好的选择(proxy)
Vue3 为什么要用 proxy
proxy 可以直接监听数组
proxy 可以监听对象而非属性。它在目标对象之间架设一层"拦截",外界对该对象的访问,都必须先经过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
proxy 可以直接劫持整个对象,并返回一个新对象
总结:
proxy 返回的是一个新对象,我们可以只操作新的对象达到的目的,而 Object.defineProperty 只能遍历对象属性直接修改。
评论