vue3 正式面市已经有一段时间了,但作为前端人却刚刚开始研究 vue3 简直太 out 了,只能老鸟晚飞靠勤来补拙了。vue 的双向绑定是我们乐于使用 vue 的重要原因之一,理解双向绑定背后的原理可以帮助我们更好的应用vue来开发。
vue2.x 的双向绑定是基于 JavaScript 的 Object.defineProperty 的get,set属性,而升级后的vue3.x 改为Proxy代理。
这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
为什么要用Proxy重构?
我们先来回顾一下 Object.defineProperty 的定义 :
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
语法:
Object.defineProperty(obj, prop, descriptor)
参数: obj 要定义属性的对象 prop 要定义或修改的属性的名称或 Symbol descriptor 要定义或修改的属性描述符
也就是说 Object.defineProperty 主要是针对对象上的属性做处理,如果是对象上不存在的属性,那它是没有办法进行处理的。这也是 vue2.x 中,对象中新增的属性不会更新的原因。
Proxy 的优点
-
Proxy 作为新标准将受到浏览器厂商重点持续的性能优化
-
Proxy 能观察的类型比 defineProperty 更丰富
-
Proxy 不兼容IE,也没有 polyfill, defineProperty 能支持到IE9
-
Object.definedProperty 是劫持对象的属性,新增元素需要再次 definedProperty。而 Proxy 劫持的是整个对象,不需要做特殊处理
使用 defineProperty 时,我们修改原来的 obj 对象就可以触发拦截,而使用 proxy,就必须修改代理对象,即 Proxy 的实例才可以触发拦截
总结
vue2.x 通过Object.defineProperty的set,get方法实现数据的双向绑定,但只能检测到对象现有的属性。 而vue3.x是通过proxy实现,好处是监听的整个对象,无论是否是新增的属性,都可以检测到,也因此vue的性能又得到了大力提升。