在最近的面试中,最多被问到的一个问题就是 Vue的数据响应式原理,由此可见其重要性,因此准备将这块知识整理成文,加深自己对这块知识的理解,希望也能帮助到你
需要注意本文是以 Vue2版本 进行讲解,好了,废话不多说,开搞!
概述
实现Vue的数据响应式,主要是借助以下三个对象实现的
- Observer
- Dep
- Watcher
总体设计上是采用 数据劫持+发布订阅模式 来实现的,接下来就上述三个对象依次进行讲解
Observer
翻译过来就是 观察者,它的主要作用是借助 Object.defineProperty,将data对象的属性转化为 getter 和 setter,从而实现对属性的访问和修改进行拦截的目的
Dep
依赖收集器,用于保存每一个属性对应的所有Watcher,并在需要更新时依次通知每一个Watcher
Watcher
订阅者,用于订阅属性的变化,在vue里Watcher主要分为如下三类
- template里使用
- computed
- watch
整体流程
这一节来讲讲上述三者是如何有机结合在一起,从而实现数据响应式的
当 Observer 转化对象属性时,每一个属性都有 单独的 一个Dep,用于收集自己的依赖
当 访问 属性时,会触发 getter,在getter里会新创建一个 Watcher 实例,并将这个Watcher实例放入到该属性对应的Dep里,从而实现依赖收集
当 更改 属性时,会触发 setter,在setter里会通知Dep进行更新,然后Dep就会遍历之前在getter里收集到的所有Watcher,并依次调用其更新回调,最终实现数据响应式
在这个流程中,三者扮演了不同的角色
- Observer: 充当 发布者,用于发布原始的更新消息
- Dep: 充当 消息中心,用于 存储订阅者Watcher 以及 转发 Observer下发的消息给Watcher
- Watcher: 充当 订阅者,用来订阅属性的变化,当收到Dep下发的更新消息时,就启动对应的更新流程
结语
这些“底层知识”虽然不会直接用于开发,但是对于排查一些疑难杂症的原因是十分有帮助的,并且也是面试的热题,因此我认为还是有必要去掌握的,好啦,over!