加入收藏 | 设为首页 | 会员中心 | 我要投稿 怀化站长网 (https://www.0745zz.cn/)- 语音技术、云资源管理、物联设备、云计算、决策智能!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

Vue 3响应式原理

发布时间:2021-02-22 14:39:05 所属栏目:外闻 来源:互联网
导读:至此,我们对响应式的基本概念有了了解,我们已经做到了收集所有响应式对象的依赖项,但是现在你可以看到代码的使用是极其繁琐的,主要是因为我们还没实现自动收集依赖项、自动触发修改。 2. Proxy 和 Reflect 上一节讲到了我们实现了基本的响应功能,但是我

至此,我们对响应式的基本概念有了了解,我们已经做到了收集所有响应式对象的依赖项,但是现在你可以看到代码的使用是极其繁琐的,主要是因为我们还没实现自动收集依赖项、自动触发修改。

2. Proxy 和 Reflect

上一节讲到了我们实现了基本的响应功能,但是我们目前还是手动进行依赖收集和触发更新的。

解决这个问题的方法应该是:

  •  当访问(GET)一个属性时,我们就调用 track(obj, <property>) 自动收集依赖项(存储 effect)
  •  当修改(SET)一个属性时,我们就调用 trigger(obj, <property> 自动触发更新(执行存储的effect)

那么现在问题就是,我们如何在访问或修改一个属性时做到这样的事情?也即是如何拦截这种 GET 和 SET 操作?

Vue 2中我们使用 ES5 中的 Object.defineProperty 来拦截 GET 和 SET。

Vue 3中我们将使用 ES6 中的 Reflect 和 Proxy。(注意:Vue 3不再支持IE浏览器,所以可以用比较多的高级特性)

我们先来看一下怎么输出一个对象的一个属性值,可以用下面这三种方法:

  •  使用 . => obj.a
  •  使用 [] => obj['a']
  •  使用 ES6 中的 Reflect => Reflect.get(obj, 'a')

这三种方法都是可行的,但是 Reflect 有非常强大的能力,后面会讲到。

Proxy

我们先来看看 Proxy,Proxy 是另一个对象的占位符,默认是对这个对象的委托。你可以在这里查看 Proxy 更详细的用法。


 

这段代码的输出结果就是错误的,这是什么情况?难道是原型继承写错了吗?我们尝试把Proxy相关代码去掉,发现输出是正常的......

这个问题其实就出在 return target[key]这一行:

  1.  当读取 childObj.b 时,childObj 上没有属性 b,因此会从原型链上查找
  2.  原型链是 proxiedObj
  3.  读取 proxiedObj.b 时,会触发Proxy捕捉器(trap)中的 get,这直接从原始对象中返回了 target[key]
  4.  这里target[key] 中 key 是一个 getter,因此这个 getter 中的上下文 this 即为target,这里的 target 就是 obj,因此直接返回了 1。

(编辑:怀化站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读