当前位置:   article > 正文

Vue3 响应式原理_vue3响应式原理

vue3响应式原理

响应式原理

Vue中的响应式通过三种响应式解决方案,defineProperty、Proxy、value setter。

Vue2中使用 defineProperty API 实现响应式,存在的缺陷就是删除 obj.count 属性,set 函数不会执行,所以Vue2中需要使用 $delete 函数区删除数据。如下代码实现了简易的响应式功能,定义一个对象obj,使用 defineProperty 代理了 count 属性。这就实现了 obj 对象的 value 属性实现了拦截,读取 count 属性的时候执行 get 函数,修改 count 属性的时候 set 函数,并在 set 函数内部重新计算了 double 。

  1. let getDouble = n=>n*2
  2. let obj = {}
  3. let count = 1
  4. let double = getDouble(count)
  5. Object.defineProperty(obj,'count',{
  6. get(){
  7. return count
  8. },
  9. set(val){
  10. count = val
  11. double = getDouble(val)
  12. }
  13. })
  14. console.log(double) // 2
  15. obj.count = 2
  16. console.log(double) // 4

Vue3 的响应式机制是基于 Proxy 实现的,解决了 Vue2 响应式的缺陷。如以下代码, 通过 new Proxy 代理了 obj 对象,然后通过 get、set、deleteProperty 函数代理了对象的读取、修改和删除操作,从而实现了响应式的功能。

  1. let getDouble = n=>n*2
  2. let obj = {}
  3. let count = 1
  4. let double = getDouble(count)
  5. let proxy = new Proxy(obj, {
  6. get : function (target, prop) {
  7. return target[prop]
  8. },
  9. set : function (target, prop, value) {
  10. target[prop] = value;
  11. if(prop === 'count') {
  12. double = getDouble(value)
  13. }
  14. },
  15. deleteProperty(target, prop) {
  16. delete target[prop]
  17. if(prop === 'count') {
  18. double = NaN
  19. }
  20. }
  21. })
  22. console.log(obj.count, double) // undefined 2
  23. proxy.count = 2
  24. console.log(obj.count, double) // 2 4
  25. delete proxy.count
  26. console.log(obj.count, double) // undefined NaN

Vue3 Proxy 实现的功能和 Vue2 的 definePropery 类似,都能够在用户修改数据的时候出发 set 函数,更新 double ,Proxy 还完善了 definePropery 的缺陷,如监听属性的删除。Proxy 是针对对象来监听,而不是针对某个具体属性,所以不仅可以代理定义时不存在的属性,还可以代理更丰富的数据结构,比如 Map、Set ...,还能通过 deleteProperty 实现对删除操作的代理。

Vue3 除了 Proxy 还有另一个响应式实现的逻辑,利用对象的 get 和 set 函数来进行监听,这种响应式的实现方式,只能拦截某一个属性的修改,这也是 Vue3 中 ref 这个 API 实现的。如下代码中,拦截了 count 的value 属性,并且拦截了 set 操作,也能实现类似的功能。

  1. let getDouble = n=>n*2
  2. let _value = 1
  3. double = getDouble(_value)
  4. let count = {
  5. get value() {
  6. return _value
  7. },
  8. set value(val) {
  9. _value = val
  10. double = getDouble(_value)
  11. }
  12. }
  13. console.log(count.value, double) // 1 2
  14. count.value = 2
  15. console.log(count.value, double) // 2 4

这三种实现原理对比如下:

实现原理definePropertyProxyvalue setter
实际场景Vue2 响应式Vue3 reactiveVue3 ref
优势兼容性基于Proxy实现真正的拦截实现简单
劣势数组和属性删除等拦截不了不兼容IE11只拦截了value属性
实际应用Vue2Vue3 复杂数据结构Vue3 简单数据结构
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/283921
推荐阅读
相关标签
  

闽ICP备14008679号