中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue的$set怎么實現

發布時間:2022-12-16 09:07:33 來源:億速云 閱讀:118 作者:iii 欄目:編程語言

這篇文章主要講解了“Vue的$set怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Vue的$set怎么實現”吧!

應用場景

 let dataArr = ["item1"];
 let dataObject = {
      name: "ccs"
    };

    dataArr[2] = "item2";
    dataObject.age = 22;
    響應失敗,頁面沒有顯示更新新增的數據

    this.$set(this.dataArr,2,'item2')
    this.$set(this.dataObject,'age',22)
    響應成功,頁面顯示更新新增的數據

set實現

接下來我們看一下$set在Vue中的定義

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)}`
    );
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key);
    target.splice(key, 1, val);
    return val;
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }
  const ob = (target: any).__ob__;
  if (target._isVue || (ob && ob.vmCount)) {
    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) {
    target[key] = val;
    return val;
  }
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
}

在源碼中首先判斷set的目標是否是undefined基本類型如果是undefined基本類型就報錯,
因為用戶不應該往undefined和基本類型中set東西
然后又判斷了目標是否是數組與key是不是合法的index,合法的index是指值為大于等于0的整數,
如果兩個條件都成立就對目標數組調用splice方法插入或者修改數組
這里的splice不是普通的splice是王維詩里的splice,是被vue代理重寫過的splice

數組實現響應

$set實現數組修改響應的方式是代理重寫的數組的一部分方法,接下來我們看一下具體實現

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]
function def(obj, key, val, enumerable) {
    Object.defineProperty(obj, key, {
        value: val,
        enumerable: !!enumerable,
        writable: true,
        configurable: true
    });
}
methodsToPatch.forEach(function (method) {
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    ob.dep.notify()
    return result
  })
})

vue中代理重寫的不只是splice,有push、pop、shift、unshift、splice、sort、reverse這七個方法, 首先執行了const result = original.apply(this, args)執行原本數組的方法并獲取它的值,接下來判斷如果是往數組中添加值就將新添加的值也實現響應式,
最后一步拿到這個數組的_ob_對象_ob_里的dep進行派發更新。
想深入了解vue的響應式可以查閱往期文章
面試官問你Vue2的響應式原理,你怎么答? - 掘金 (juejin.cn)

對象實現響應

$set中下半部分的邏輯就是用來處理對象響應的,我們接著往下看

  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }
  const ob = (target: any).__ob__;
  if (!ob) {
    target[key] = val;
    return val;
  }
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;

首先判斷了屬性如果在目標對象中直接return結束邏輯,
因為vue只有添加目標對象中原本沒有的屬性時才會失去響應
例如 let obj={}  obj.name='ccs'
vue在初始化的時候會將data里的所有屬性都變成響應式,如果的值是對象或者數組則會new一個Observer實例儲存在__ob__,想深入了解vue的響應式可以查閱往期文章
面試官問你Vue2的響應式原理,你怎么答? - 掘金 (juejin.cn)
拿到這個對象的_ob_進行判斷,如果不存在就說明是未經過vue初始化的普通對象而不是響應式對象否則就手動通過defineReactive為屬性添加get方法與set方法實現響應
然后手動調用dep里的notify()發布更新。

感謝各位的閱讀,以上就是“Vue的$set怎么實現”的內容了,經過本文的學習后,相信大家對Vue的$set怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

锦州市| 德江县| 关岭| 福清市| 汨罗市| 巢湖市| 方城县| 遵化市| 怀仁县| 康马县| 平陆县| 许昌市| 吉林市| 彰化市| 岗巴县| 罗城| 江孜县| 佛冈县| 永平县| 莎车县| 临江市| 忻州市| 山阴县| 饶阳县| 滦平县| 兰坪| 甘孜县| 开远市| 凯里市| 定日县| 上犹县| 卢龙县| 永平县| 嘉善县| 五峰| 赞皇县| 正安县| 宜城市| 江川县| 农安县| 荥经县|