iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
1
Modern Web

技術在走,Vue.js 要有系列 第 17

|D17| 從原始碼看 Vue 響應式原理 (3) - Observer

內文寫在註解

// src/core/observer/index.js

/*********************************************************
   Observer 是一個 class,
   作用是給物件的所有屬性加上 getters 和 setter
**********************************************************/
export class Observer {
  value: any;
  dep: Dep;
  vmCount: number;

  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    /*************************************************
      執行 def 把自身實例加到數據對象的 value 的 _ob_ 屬性上
      def function 是 Object.defineProperty 的封裝
    **************************************************/
    def(value, '__ob__', this)
    if (Array.isArray(value)) {
      const augment = hasProto
        ? protoAugment
        : copyAugment
      augment(value, arrayMethods, arrayKeys)
      this.observeArray(value)
    } else {
      this.walk(value)
    }
  }

  /*************************************************
    在元件中我們定義了 data 有哪些屬性,
    defineReactive 給物件的所有屬性加上 getters 和 setter
  **************************************************/
  walk (obj: Object) {
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i])
    }
  }

  //...
}

/*********************************************************
    observe 用來監測數據的變化,給非 VNode 物件加上 Observer
**********************************************************/
export function observe (value: any, asRootData: ?boolean): Observer | void {
  if (!isObject(value) || value instanceof VNode) {
    return
  }
  let ob: Observer | void
  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
    ob = value.__ob__
  } else if (
    shouldObserve &&
    !isServerRendering() &&
    (Array.isArray(value) || isPlainObject(value)) &&
    Object.isExtensible(value) &&
    !value._isVue
  ) {
    ob = new Observer(value)
  }
  if (asRootData && ob) {
    ob.vmCount++
  }
  return ob
}


// src/core/util/lang.js
/*************************************************
  def function 是 Object.defineProperty 的封裝,
  若印出 data 上物件類型的數據,會看到該物件有 _ob_ 屬性
**************************************************/
export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
  Object.defineProperty(obj, key, {
    value: val,
    enumerable: !!enumerable,
    writable: true,
    configurable: true
  })
}

上一篇
|D16| 從原始碼看 Vue 響應式原理 (2) MVVM
下一篇
|D18| 從原始碼看 Vue 響應式原理 (4) - Dep
系列文
技術在走,Vue.js 要有30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言