龙空技术网

Vue源码逐行解析十四 Observe函数 (观察对象的getter/setters)

小小的码农 90

前言:

眼前你们对“jssetter”大概比较看重,姐妹们都想要学习一些“jssetter”的相关知识。那么小编同时在网上网罗了一些有关“jssetter””的相关资讯,希望咱们能喜欢,各位老铁们快快来学习一下吧!

我们打开文件 `src/core/observer/index.js`,找到定义`Observer`函数的代码:

export class Observer {  value: any;  dep: Dep;  vmCount: number; // number of vms that have this object as root $data  constructor (value: any) {    this.value = value    // 用来给数据添加Dep依赖    this.dep = new Dep()    this.vmCount = 0    def(value, '__ob__', this)    if (Array.isArray(value)) {      if (hasProto) {        protoAugment(value, arrayMethods)      } else {        copyAugment(value, arrayMethods, arrayKeys)      }      this.observeArray(value)    } else {      this.walk(value)    }  }  /**   * Walk through all properties and convert them into   * getter/setters. This method should only be called when   * value type is Object.   */  walk (obj: Object) {    const keys = Object.keys(obj)    for (let i = 0; i < keys.length; i++) {      defineReactive(obj, keys[i])    }  }  /**   * Observe a list of Array items.   */  observeArray (items: Array<any>) {    for (let i = 0, l = items.length; i < l; i++) {      observe(items[i])    }  }}

构造函数

constructor (value: any) {    this.value = value    // 用来给数据添加Dep依赖    this.dep = new Dep()    this.vmCount = 0    def(value, '__ob__', this)    if (Array.isArray(value)) {      if (hasProto) {        protoAugment(value, arrayMethods)      } else {        copyAugment(value, arrayMethods, arrayKeys)      }      this.observeArray(value)    } else {      this.walk(value)    }  }

首先是给 `value` 对象添加了 '__ob__'属性。

然后判断`value`是否是数组,如果是数组的话,就对数组进行处理,然后在调用`observeArray`函数对`value`进行处理。

>arrayMethods有如下具体方法,这些方法就是vue给我们实现了双向绑定[ 'push','pop', 'shift', 'unshift', 'splice','sort', 'reverse']

`observeArray`代码如下:

 /**   * Observe a list of Array items.   */  observeArray (items: Array<any>) {    for (let i = 0, l = items.length; i < l; i++) {      observe(items[i])    }  }}

可以看到对数组进行了遍历监听,这就是为什么`Object.defineProperty`是不支持数组监听的,但是vue里面数组的改变还是一个响应式的特性。

接下来我们看看`walk`的代码,比较简单。

 walk (obj: Object) {    const keys = Object.keys(obj)    for (let i = 0; i < keys.length; i++) {      defineReactive(obj, keys[i])    }  }

可以看到首先是获取了所有的`keys`,然后一一进行监听。

以上基本就是 “Observer” 类的基本功能了,如有错误欢迎指出,谢谢。

标签: #jssetter