浅析从vue源码看观察者模式

观察者模式

首先话题下来,我们得反问一下自己,什么是观察者模式?

概念

观察者模式(Observer):通常又被称作为发布-订阅者模式。它定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖于它的对象都会得到通知并自动更新,解决了主体对象与观察者之间功能的耦合。

讲个故事

上面对于观察者模式的概念可能会比较官方化,所以我们讲个故事来理解它。

A:是共产党派往国民党密探,代号 001(发布者)
B:是共产党的通信人员,负责与 A 进行秘密交接(订阅者)

  1. A 日常工作就是在明面采集国民党的一些情报
  2. B 则负责暗中观察着 A
  3. 一旦 A 传递出一些有关国民党的消息(更多时候需要对消息进行封装传递,后面根据源码具体分析)
  4. B 会立马订阅到该消息,然后做一些相对应的变更,比如说通知共产党们做一些事情应对国民党的一些动作。

适用性

以下任一场景都可以使用观察者模式

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。讲这两者封装在独立的对象中可以让它们可以各自独立的改变和复用
  2. 当一个对象的改变的时候,需要同时改变其它对象,但是却不知道具体多少对象有待改变
  3. 当一个对象必须通知其它对象,但是却不知道具体对象到底是谁。换句话说,你不希望这些对象是紧密耦合的。

vue 对于观察者模式的使用

vue 使用到观察者模式的地方有很多,这里我们主要谈谈对于数据初始化这一块的。

var vm = new Vue({
 data () {
  return {
   a: 'hello vue'
  }
 }
})

1、实现数据劫持

上图我们可以看到,vue 是利用的是 Object.defineProperty() 对数据进行劫持。 并在数据传递变更的时候封装了一层中转站,即我们看到的 Dep 和 Watcher 两个类。

这一小节,我们只看如何通过观察者模式对数据进行劫持。

1.1、递归遍历

我们都知道,vue 对于 data 里面的数据都做了劫持的,那只能对对象进行遍历从而完成每个属性的劫持,源码具体如下

walk (obj: Object) {
 const keys = Object.keys(obj)
 // 遍历将其变成 vue 的访问器属性
 for (let i = 0; i < keys.length; i++) {
  defineReactive(obj, keys[i], obj[keys[i]])
 }
}
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/458.html