vue3中双向绑定的实现
vue3的双向绑定改变,用一句话来描述:vue3的双向绑定原理由Object.defineProperty
改为基于ES6的Proxy
代理来实现。
为什么要替换Object.defineProperty
- vue官网在深入响应式原理中解释,由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,也就是:
- 对象属性的添加和删除,无法监听
- 数组索引和长度的变更,无法监听
- vue2.x为了给每个属性添加setter/getter,会递归调用,而Proxy能劫持整个对象,相比而言更高效
Proxy和Reflect
Proxy可以理解为“拦截”目标对象,外界对该对象的访问都会拦截,因此可以对外界的访问进行过滤和改写。
Reflect可以理解为一个方法的集合,一些明显属于语言层面的方法,被放到了Reflect上。现阶段,某些方法同时在Object和Reflect上部署,但未来一些新方法只在Reflect上部署。
1 | var obj = { |
实现
在上一篇《vue双向绑定原理》的基础上,重写监听器observe,上一篇observe的实现如下:
1 | function observe ($data, vm) { |
使用Proxy数据劫持的方式来实现:
1 | observe(data) { |
这段代码里把代理器返回的对象代理到this.$data,即this.$data是代理后的对象,外部每次对this.$data进行操作时,实际上执行的是这段代码里handler对象上的方法。
参考: