🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
vue的双向绑定是基于数据劫持的方式实现的,vue2数据劫持用的object.defineProperty()来劫持对象的属性,vue3是直接劫持对象,set数据变化的时候,发布消息给订阅者,触发相应的监听回调。 ![](https://img.kancloud.cn/26/03/260333d5d1b86e8034b10be451744047_730x390.png) **执行过程:** 当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面Vue 会遍历 data 选项中的属性,并用 Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;另一方面,Vue 的指令编译器Compile 对元素节点的指令进行扫描和解析,初始化视图,并订阅 Watcher 来更新视图, 此时Wather 会将自己添加到消息订阅器中(Dep),初始化完毕。 当数据发生变化时,Observer 中的 getter 方法被触发(注意这里触发什么),getter 会立即调用Dep.notify(),Dep 开始遍历所有的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。同理当表单输入内容发生变化时, 就会触发setter,watcher监听机制就会执行, watcher通知Vue生成新的VDOM树,再通过render函数进行渲染,生成真实DOM 。 **Object.defineProperty 的缺点**: 总体上说致命的缺点是: * 不能监听数组的变化 * 必须遍历对象的每个属性 * 必须深层遍历嵌套的对象 **ES6中的Proxy的优点**: 总的来说呢,Proxy是刚好解决了上述**Object.defineProperty**的缺点: **针对对象:**针对整个对象,而不是对象的某个属性,所以也就不需要对 keys 进行遍历。 **支持数组:**Proxy 不需要对数组的方法进行重载,省去了众多 hack,减少代码量等于减少了维护成本,而且标准的就是最好的。 当然除此之外还有以下几个原因: Proxy 的第二个参数可以有 13 种拦截方法,这比起 Object.defineProperty() 要更加丰富 Proxy 作为新标准受到浏览器厂商的重点关注和性能优化,相比之下 Object.defineProperty() 是一个已有的老方法。