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

Vue中$nextTick實現源碼解析

 更新時間:2022年10月25日 08:41:39   作者:錢得樂  
這篇文章主要為大家介紹了Vue中$nextTick實現源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

先看一個簡單的問題

<template>
  <div @click="handleClick" ref="div">{{ text }}</div
</template>
<script>
  export default {
    data() {
      return {
        text: 'old'
      }
    },
    methods: {
      handleClick() {
        this.text = 'new'
        console.log(this.$refs.div.innerText)
      }
    }
  }
</script>

此時打印的結果是什么呢?是 'old'。如果想讓它打印 'new',使用 nextTick 稍加改造就可以

this.$nextTick(() => {
  console.log(this.$refs.div.innerText)
})

內部實現

但是你想過它內部是怎么實現的么,和我們寫 setTimeout 有什么區(qū)別呢?

因為平時工作使用的是Vue2,所以我就以Vue2的最新版本2.6.14為例進行分析,Vue3的實現應該也是大同小異。

源碼地址:github.com/vuejs/vue/b…

為了方便閱讀我刪掉了注釋,只關注最重要的實現

if (typeof Promise !== 'undefined' && isNative(Promise)) {
  const p = Promise.resolve()
  timerFunc = () => {
    p.then(flushCallbacks)
    if (isIOS) setTimeout(noop)
  }
  isUsingMicroTask = true
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
  isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
  let counter = 1
  const observer = new MutationObserver(flushCallbacks)
  const textNode = document.createTextNode(String(counter))
  observer.observe(textNode, {
    characterData: true
  })
  timerFunc = () => {
    counter = (counter + 1) % 2
    textNode.data = String(counter)
  }
  isUsingMicroTask = true
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
  timerFunc = () => {
    setImmediate(flushCallbacks)
  }
} else {
  timerFunc = () => {
    setTimeout(flushCallbacks, 0)
  }
}

先大概掃一遍可知 $nextTick 主要是通過微任務來實現的,其實在2.5版本中,是采用宏任務與微任務相結合的方式實現的,但因為在渲染和事件處理中一些比較怪異的行為(感興趣的話可以看下issue),所以最終統(tǒng)一采用了微任務。

先看第一塊:

if (typeof Promise !== 'undefined' && isNative(Promise)) {
  const p = Promise.resolve()
  timerFunc = () => {
    p.then(flushCallbacks)
    if (isIOS) setTimeout(noop)
  }
  isUsingMicroTask = true
}

如果可以使用 Promise ,就采用 promise.then 的方式去執(zhí)行回調,將任務在下一個tick執(zhí)行。但是其中 if (isIOS) setTimeout(noop) 這句話是在做什么呢?在iOS >= 9.3.3的UIWebView中,定義的回調函數通過 Promise 的方式推到微任務隊列后,隊列不刷新,需要靠 setTimeout 來強制更新一下,noop 就是一個空函數。

再看第二塊:

else if (!isIE && typeof MutationObserver !== 'undefined' && (
  isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
  let counter = 1
  const observer = new MutationObserver(flushCallbacks)
  const textNode = document.createTextNode(String(counter))
  observer.observe(textNode, {
    characterData: true
  })
  timerFunc = () => {
    counter = (counter + 1) % 2
    textNode.data = String(counter)
  }
  isUsingMicroTask = true
}

如果不能用 Promise 就降級使用 MutationObserver。創(chuàng)建了一個文本節(jié)點,并通過 observer 去觀察文本節(jié)點的變化。 characterData: true 這個配置就是當文字變化的時候就會執(zhí)行回調。(counter + 1) % 2 會使文本節(jié)點的文字在 0 、 1 、 0 、 1之間不同變化,這樣就會被 observer 觀察到。MutationObserver 也是微任務。

然后是第三塊:

else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { 
  timerFunc = () => { 
    setImmediate(flushCallbacks) 
  } 
}

當微任務都不被支持時,就要使用宏任務了。其實大多數情況下都不會走到這里,因為 setImmediate 并沒有成為正式的標準,并且兼容性很差。

最后是第四塊:

else {
  timerFunc = () => {
    setTimeout(flushCallbacks, 0)
  }
}

最后在所有方案都行不通時,只能采用 setTimeout 的方式。之所以有第三塊是因為雖然都是宏任務,但是 setImmediate 會比 setTimeout 快,所以MDN上才會說 setTimeout(fn, 0) 不能成為 setImmediate 的polyfill。就像作者在注釋中寫的那樣:它仍然是比 setTimeout 更好的選擇。

一步一步分析了 $nextTick 源碼后,你是否對它的用法理解更加透徹了呢?

以上就是Vue中$nextTick實現源碼解析的詳細內容,更多關于Vue $nextTick解析的資料請關注腳本之家其它相關文章!

相關文章

  • Vue.js?模板語法和數據綁定

    Vue.js?模板語法和數據綁定

    這篇文章主要介紹了Vue.js?模板語法和數據綁定,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • vue中錨點的三種方法

    vue中錨點的三種方法

    本文給大家?guī)砹藇ue中錨點的三種方法,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2018-07-07
  • vue項目啟動端口更改的實現

    vue項目啟動端口更改的實現

    在Vue前端項目中,可以通過修改配置文件來指定啟動的端口號,本文就來介紹 一下vue項目啟動端口更改的實現,感興趣的可以了解一下
    2023-10-10
  • vue3使用vue-router的完整步驟記錄

    vue3使用vue-router的完整步驟記錄

    Vue Router是Vue.js (opens new window)官方的路由管理器,它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌,這篇文章主要給大家介紹了關于vue3使用vue-router的相關資料,需要的朋友可以參考下
    2021-06-06
  • Vue項目中使用自定義字體樣式方式

    Vue項目中使用自定義字體樣式方式

    這篇文章主要介紹了Vue項目中使用自定義字體樣式方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • VUE?v-for中的:key詳解

    VUE?v-for中的:key詳解

    這篇文章主要為大家介紹了v-for中的:key,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 基于vue3與supabase系統(tǒng)認證機制詳解

    基于vue3與supabase系統(tǒng)認證機制詳解

    這篇文章主要介紹了基于vue3與supabase系統(tǒng)認證機制,,系統(tǒng)使用基于 JWT (JSON Web Token) 的認證方式,提供了安全可靠的用戶身份管理機制,需要的朋友可以參考下
    2025-04-04
  • Vue動畫之第三方類庫實現動畫方式

    Vue動畫之第三方類庫實現動畫方式

    這篇文章主要介紹了Vue動畫之第三方類庫實現動畫方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue3配置代理實現axios請求本地接口返回PG庫數據

    vue3配置代理實現axios請求本地接口返回PG庫數據

    這篇文章主要為大家詳細介紹了vue3配置代理實現axios請求本地接口返回PG庫數據的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-03-03
  • vue2和vue3實現圖片懶加載方式

    vue2和vue3實現圖片懶加載方式

    這篇文章主要介紹了vue2和vue3實現圖片懶加載方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論

广平县| 磐石市| 兴业县| 盐山县| 虞城县| 罗山县| 武川县| 霍城县| 曲阳县| 苍溪县| 珠海市| 饶阳县| 翁牛特旗| 出国| 克什克腾旗| 元阳县| 赫章县| 达日县| 北碚区| 洞口县| 枞阳县| 马龙县| 新建县| 塘沽区| 山阳县| 岳阳县| 鄯善县| 丰原市| 准格尔旗| 荆州市| 栾川县| 公安县| 岳西县| 张家港市| 汕尾市| 辽中县| 汨罗市| 城步| 三亚市| 曲周县| 泗水县|