简述
事实上,响应式并不是 Vue3
的新概念,它是一个核心概念。在实际代码中,响应式系统经常与组件化相提并论。更进一步的说,组件化赋予了开发者模块化代码的能力,而响应式系统则让开发者可以通过数据控制组件的呈现方式。
不过这东西从本质上来讲,其实就是劫持数据的变化,在数据变化后自动的执行一些副作用函数。
如果你大致的了解过这个东西,你大概会知道,Vue2
和 Vue3
的响应式系统实现有些略微不同。
从表象上来说,Vue2
的响应式系统是黑盒。Vue2
承包了一切工作,你只需要将数据定义在诸如 data
、props
、computed
等选项中就行。而 Vue3
则是把这个决定权交给了开发者。由开发者来决定究竟哪些数据应该是响应式的。
从实现上来说,Vue2
使用 Object.defineproperty
来实现数据劫持,而 Vue3
则使用了 proxy
。
从逻辑上讲,其实二者是相同的,都是为了实现核心的数据劫持。
不过 Vue
毕竟是一个投入到实际生产中使用的框架,仅仅完成理论上的实现当然是不行的。从 Object.defineproperty
到 proxy
的切换实际上也表现出了一些技术上的选择。
简单来说,因为 Vue2
对响应式数据黑盒化的设计,在框架初始化的时候,会递归遍历所有数据,然后使用 Object.defineproperty
来做劫持。这是一个解决方案,但并不够好。因为首先会付出很多性能消耗,其次,并不是每一条数据都需要变成响应式的。递归消耗的性能支出是否合算,全看开发者的具体实现方式。另外,Object.defineproperty
也不能监听到对象属性的新增与删除。
所以 Vue3
使用了 proxy
和显式的 reactice API
。这样不仅可以让开发者自行决定哪些数据需要变成响应式的,还能减少劫持时的数据消耗。
除此之外,在具体实现中,Vue3
也做了一些调整来优化性能。更具体的东西,来直接看源码吧。