vue.$set實現原理


上源碼:

export function set (target: Array<any> | Object, key: any, val: any): any {
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  // 判斷目標值是否為數組,並且key值是否為有效的數組索引
if (Array.isArray(target) && isValidArrayIndex(key)) {
  // 對比數組的key值和數組長度,取較大值設置為數組的長度 target.length
= Math.max(target.length, key)
  // 替換目標值 target.splice(key,
1, val) return val }
  // 如果目標值是對象,並且key值是目標值存在的有效key值,並且不是原型上的key值
if (key in target && !(key in Object.prototype)) {
  // 直接更改目標值 target[key]
= val return val } const ob = (target: any).__ob__ // 判斷目標值是否為響應式的 if (target._isVue || (ob && ob.vmCount)) { // 如果是vue根實例,就警告 process.env.NODE_ENV !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return val } if (!ob) { // 如果目標值不是響應式的,那么值需要給對應的key賦值 target[key] = val return val }
  // 其他情況,目標值是響應式的,就通過Object.defineProperty進行數據監聽 defineReactive(ob.value, key, val)
  // 通知更新dom操作 ob.dep.notify()
return val }

大概流程就是:

  1.判斷目標值是否為有效值,不是有效值直接停止

  2.判斷是否為數組,並且key值是否為有效的key值

    如果是數組,就選擇數組的長度和key值取較大值作為數組的新的length值,並且替換目標值

    splice方法,重寫了,所以執行splice,會雙向數據綁定

  3.判斷目標值是否為響應式的__ob__

    如果是vue實例,直接不行

    如果不是響應式的數據,就是普通的修改對象操作

    如果是響應式數據,那就通過Object.defineProperty進行數據劫持

  4.通知dom更新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM