最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

你知道Vue中神奇的$set是如何實(shí)現(xiàn)的嗎?

 更新時(shí)間:2022年12月13日 15:43:13   作者:清風(fēng)丶  
在日常開(kāi)發(fā)中,$set的也是一個(gè)非常實(shí)用的API。但是我們知其然更要知其所以然,接下來(lái)就跟隨小編一起看一下Vue中的$set是如何實(shí)現(xiàn)的吧

前言

在日常開(kāi)發(fā)中,$set的也是一個(gè)非常實(shí)用的API,因?yàn)閂ue2實(shí)現(xiàn)響應(yīng)式的核心是利用了ES5的Object.defineProperty,當(dāng)我們通過(guò)直接修改數(shù)組下標(biāo)更改數(shù)組或者給對(duì)象添加新的屬性,這個(gè)時(shí)候Object.defineproperty是監(jiān)聽(tīng)不到數(shù)據(jù)的變化的,這時(shí)候大家就會(huì)用上$set,讓修改的操作也實(shí)現(xiàn)響應(yīng),我們知其然更要知其所以然,接下來(lái)看一下Vue中的$set是如何實(shí)現(xiàn)的

應(yīng)用場(chǎng)景

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

    dataArr[2] = "item2";
    dataObject.age = 22;
//    響應(yīng)失敗,頁(yè)面沒(méi)有顯示更新新增的數(shù)據(jù)

    this.$set(this.dataArr,2,'item2')
    this.$set(this.dataObject,'age',22)
//響應(yīng)成功,頁(yè)面顯示更新新增的數(shù)據(jù)

set實(shí)現(xiàn)

接下來(lái)我們看一下$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的目標(biāo)是否是undefined和基本類(lèi)型如果是undefined或基本類(lèi)型就報(bào)錯(cuò),因?yàn)橛脩舨粦?yīng)該往undefined和基本類(lèi)型中set東西,然后又判斷了目標(biāo)是否是數(shù)組與key是不是合法的index,合法的index是指值為大于等于0的整數(shù),如果兩個(gè)條件都成立就對(duì)目標(biāo)數(shù)組調(diào)用splice方法插入或者修改數(shù)組,這里的splice不是普通的splice是王維詩(shī)里的splice,是被vue代理重寫(xiě)過(guò)的splice

數(shù)組實(shí)現(xiàn)響應(yīng)

$set實(shí)現(xiàn)數(shù)組修改響應(yīng)的方式是代理重寫(xiě)的數(shù)組的一部分方法,接下來(lái)我們看一下具體實(shí)現(xiàn)

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中代理重寫(xiě)的不只是splice,有push、pop、shift、unshift、splice、sort、reverse這七個(gè)方法, 首先執(zhí)行了const result = original.apply(this, args)執(zhí)行原本數(shù)組的方法并獲取它的值,接下來(lái)判斷如果是往數(shù)組中添加值就將新添加的值也實(shí)現(xiàn)響應(yīng)式,最后一步拿到這個(gè)數(shù)組的_ob_對(duì)象對(duì)_ob_里的dep進(jìn)行派發(fā)更新。

想深入了解vue的響應(yīng)式可以查閱往期文章面試官問(wèn)你Vue2的響應(yīng)式原理,你怎么答?

對(duì)象實(shí)現(xiàn)響應(yīng)

$set中下半部分的邏輯就是用來(lái)處理對(duì)象響應(yīng)的,我們接著往下看

  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;

首先判斷了屬性如果在目標(biāo)對(duì)象中直接return結(jié)束邏輯,因?yàn)関ue只有添加目標(biāo)對(duì)象中原本沒(méi)有的屬性時(shí)才會(huì)失去響應(yīng)

例如 let obj={} obj.name='ccs',

vue在初始化的時(shí)候會(huì)將data里的所有屬性都變成響應(yīng)式,如果的值是對(duì)象或者數(shù)組則會(huì)new一個(gè)Observer實(shí)例儲(chǔ)存在__ob__,想深入了解vue的響應(yīng)式可以查閱往期文章面試官問(wèn)你Vue2的響應(yīng)式原理,你怎么答

拿到這個(gè)對(duì)象的_ob_進(jìn)行判斷,如果不存在就說(shuō)明是未經(jīng)過(guò)vue初始化的普通對(duì)象而不是響應(yīng)式對(duì)象 否則就手動(dòng)通過(guò)defineReactive為屬性添加get方法與set方法實(shí)現(xiàn)響應(yīng),然后手動(dòng)調(diào)用dep里的notify()發(fā)布更新。

總結(jié)

vue中$set方法對(duì)數(shù)組和對(duì)象的處理本質(zhì)上的一樣的,對(duì)新增的值添加響應(yīng)然后手動(dòng)觸發(fā)派發(fā)更新。

以上就是你知道Vue中神奇的$set是如何實(shí)現(xiàn)的嗎?的詳細(xì)內(nèi)容,更多關(guān)于Vue實(shí)現(xiàn)$set的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue之bus總線的簡(jiǎn)單使用解讀

    vue之bus總線的簡(jiǎn)單使用解讀

    這篇文章主要介紹了vue之bus總線的簡(jiǎn)單使用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue usePop彈窗控制器的實(shí)現(xiàn)

    vue usePop彈窗控制器的實(shí)現(xiàn)

    本文主要介紹了vue usePop彈窗控制器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue+elemen實(shí)現(xiàn)el-tooltip在文本超出區(qū)域后浮現(xiàn)

    vue+elemen實(shí)現(xiàn)el-tooltip在文本超出區(qū)域后浮現(xiàn)

    el-tooltip組件本身就是懸浮提示功能,在對(duì)它進(jìn)行二次封裝時(shí),實(shí)現(xiàn)超出的文本浮現(xiàn),本文就來(lái)介紹一下vue+elemen實(shí)現(xiàn)el-tooltip在文本超出區(qū)域后浮現(xiàn),感興趣的可以了解一下
    2023-12-12
  • Ant Design的Table組件去除

    Ant Design的Table組件去除

    這篇文章主要介紹了Ant Design的Table組件去除“取消排序”選項(xiàng)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • 手把手教你Vue3實(shí)現(xiàn)路由跳轉(zhuǎn)

    手把手教你Vue3實(shí)現(xiàn)路由跳轉(zhuǎn)

    Vue Router是Vue.js的官方路由器,它與Vue.js核心深度集成,使使用Vue.js構(gòu)建單頁(yè)應(yīng)用程序變得輕而易舉,下面這篇文章主要給大家介紹了關(guān)于Vue3實(shí)現(xiàn)路由跳轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • vue3+vue-router+vite實(shí)現(xiàn)動(dòng)態(tài)路由的全過(guò)程

    vue3+vue-router+vite實(shí)現(xiàn)動(dòng)態(tài)路由的全過(guò)程

    動(dòng)態(tài)路由是根據(jù)不同情況實(shí)時(shí)變化的路由,在權(quán)限管理系統(tǒng)中,動(dòng)態(tài)路由常用于根據(jù)用戶角色分配不同的菜單和功能,這篇文章主要介紹了vue3+vue-router+vite實(shí)現(xiàn)動(dòng)態(tài)路由的相關(guān)資料,需要的朋友可以參考下
    2024-10-10
  • elementui之封裝下載模板和導(dǎo)入文件組件方式

    elementui之封裝下載模板和導(dǎo)入文件組件方式

    這篇文章主要介紹了關(guān)于elementui之封裝下載模板和導(dǎo)入文件組件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理

    Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理

    當(dāng)我設(shè)置了max-height,就會(huì)在表格右側(cè)出現(xiàn)一列空白的占位,本文主要介紹了Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理,感興趣的可以了解一下
    2023-09-09
  • vue2.0中組件傳值的幾種方式總結(jié)

    vue2.0中組件傳值的幾種方式總結(jié)

    這篇文章主要介紹了vue2.0中組件傳值的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Vue項(xiàng)目導(dǎo)入導(dǎo)出文件功能以及導(dǎo)出文件后亂碼問(wèn)題及解決

    Vue項(xiàng)目導(dǎo)入導(dǎo)出文件功能以及導(dǎo)出文件后亂碼問(wèn)題及解決

    這篇文章主要介紹了Vue項(xiàng)目導(dǎo)入導(dǎo)出文件功能以及導(dǎo)出文件后亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評(píng)論

康定县| 福海县| 南江县| 屏山县| 四平市| 临武县| 安阳市| 古田县| 承德市| 平和县| 平和县| 治多县| 正蓝旗| 新余市| 郴州市| 信宜市| 和静县| 普兰县| 四川省| 海口市| 依安县| 兴城市| 商水县| 绥阳县| 金阳县| 宕昌县| 高州市| 榆树市| 灵武市| 莱阳市| 房山区| 甘泉县| 岳池县| 崇左市| 综艺| 临泽县| 冀州市| 石景山区| 阿拉善左旗| 双鸭山市| 泗阳县|