美文网首页
vue源码分析(十一)核心函数之Observe

vue源码分析(十一)核心函数之Observe

作者: vue爱好者 | 来源:发表于2020-04-21 20:51 被阅读0次

    我们打开文件 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

    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,然后一一进行监听。

    相关文章

      网友评论

          本文标题:vue源码分析(十一)核心函数之Observe

          本文链接:https://www.haomeiwen.com/subject/uuekyhtx.html