聊聊Vue的数据响应式原理~

120 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。

在最近的面试中,最多被问到的一个问题就是 Vue的数据响应式原理,由此可见其重要性,因此准备将这块知识整理成文,加深自己对这块知识的理解,希望也能帮助到你

需要注意本文是以 Vue2版本 进行讲解,好了,废话不多说,开搞!

ppx2.jpg

概述

实现Vue的数据响应式,主要是借助以下三个对象实现的

  • Observer
  • Dep
  • Watcher

总体设计上是采用 数据劫持+发布订阅模式 来实现的,接下来就上述三个对象依次进行讲解

qidai.jpeg

Observer

翻译过来就是 观察者,它的主要作用是借助 Object.defineProperty,将data对象的属性转化为 gettersetter,从而实现对属性的访问和修改进行拦截的目的

Dep

依赖收集器,用于保存每一个属性对应的所有Watcher,并在需要更新时依次通知每一个Watcher

Watcher

订阅者,用于订阅属性的变化,vue中每个组件实例都对应一个watcher实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染

在vue里依赖主要分为如下三类

  • template里使用
  • computed
  • watch

整体流程

这一节来讲讲上述三者是如何有机结合在一起,从而实现数据响应式的

6662.jpg

Observer 转化对象属性时,每一个属性都有 单独的 一个Dep,用于收集自己的依赖

访问 属性时,会触发 getter,在getter里会新创建一个 Watcher 实例,并将这个Watcher实例放入到该属性对应的Dep里,从而实现依赖收集

更改 属性时,会触发 setter,在setter里会通知Dep进行更新,然后Dep就会遍历之前在getter里收集到的所有Watcher,并依次调用其更新回调,最终实现数据响应式

在这个流程中,三者扮演了不同的角色

  • Observer: 充当 发布者,用于发布原始的更新消息
  • Dep: 充当 消息中心,用于 存储订阅者Watcher 以及 转发 Observer下发的消息给Watcher
  • Watcher: 充当 订阅者,用来订阅属性的变化,当收到Dep下发的更新消息时,就启动对应的更新流程

结语

这些“底层知识”虽然不会直接用于开发,但是对于排查一些疑难杂症的原因是十分有帮助的,并且也是面试的热题,因此我认为还是有必要去掌握的,好啦,over!