得鹿梦鱼 得鹿梦鱼

数据响应式原理

定义响应式对象 defineReactive

  1. Object.getOwnPropertyDescriptor 获取需要响应式观察对象对应键的自有属性描述符信息
  2. 判断自有属性是否存在并且是可以配置的
  3. 判断自有属性不存在get或者set存在,要修改的值为空对象或者undefined是将val重置为原始值
  4. 重新自定义get和set
function defineReactiveobj, key, val, customSetter, shallow = false, mock = false{    const dep = new Dep;    const property = Object.getOwnPropertyDescriptorobj, key    if property && property.configurable === false {        return    }    const getter = property && property.get    const setter = property && property.set    if !getter  setter && val === NO_INITIAL_VALUE  arguments.length === 2 {        val = obj[key]    }    let childOb = shallow ? val && val.__ob__ : observeval, false, mock    Object.definePropertyobj, key, {    enumerable: true,    configurable: true,    get: function reactiveGetter {      const value = getter ? getter.callobj : val      if Dep.target {        dep.depend        if childOb {          childOb.dep.depend          if isArrayvalue {            dependArrayvalue          }        }      }      return isRefvalue && !shallow ? value.value : value    },    set: function reactiveSetternewVal {      const value = getter ? getter.callobj : val      if !hasChangedvalue, newVal {        return      }      if customSetter {        customSetter      }      if setter {        setter.callobj, newVal      } else if getter {        // #7981: for accessor properties without setter        return      } else if !shallow && isRefvalue && !isRefnewVal {        value.value = newVal        return      } else {        val = newVal      }      childOb = shallow ? newVal && newVal.__ob__ : observenewVal, false, mock      dep.notify    }  }  return dep}

深层对象递归观察 observe

function observevalue, shallow = false, ssrMockReactivity = false{    if value && hasOwnvalue, '__ob__' && value.__ob__ instanceof Observer {        return value.__ob__    }     return new Observervalue, shallow, ssrMockReactivity}class Observer{    constructorvalue, shallow, ssrMockReactivity{        this.dep = new Dep;        this.vmCount = 0;        defvalue, "__ob__", true        ifisArrayvalue{            ifshallow{                this.observeArrayvalue            }        } else {            const keys = Object.keysvalue            for let i = 0; i < keys.length; i++ {                const key = keys[i]                defineReactivevalue, key, {}, undefined, shallow            }        }    }    observeArrayvalue{        for let i = 0, l = value.length; i < l; i++ {            observevalue[i], false, false        }    }}

依赖收集 Dep

pendingCleanupDeps = [];class Dep {    static target;    constructor{        // uid 为全局自增数值类型        this.id = uid++;        this.sub = [];        this._pending = false    }    addSubsub{        this.sub.pushsub    }    removeSub{        this.subs[this.subs.indexOfsub] = null;        if !this._pending {            this._pending = true            pendingCleanupDeps.pushthis        }    },    depend{        ifDep.target{            Dep.target.addDepthis        }    },    notify{        const subs = this.subs.filters => s        for let i = 0, l = subs.length; i < l; i++ {            subs[i].update        }    }}