vue3 实现数据双向绑定的原理分析

1,873 阅读2分钟

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的性能又得到了大力提升。