欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中$nextTick實(shí)現(xiàn)源碼解析

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

正文

先看一個簡單的問題

<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>

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

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

內(nèi)部實(shí)現(xiàn)

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

因?yàn)槠綍r工作使用的是Vue2,所以我就以Vue2的最新版本2.6.14為例進(jìn)行分析,Vue3的實(shí)現(xiàn)應(yīng)該也是大同小異。

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

為了方便閱讀我刪掉了注釋,只關(guān)注最重要的實(shí)現(xiàn)

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 主要是通過微任務(wù)來實(shí)現(xiàn)的,其實(shí)在2.5版本中,是采用宏任務(wù)與微任務(wù)相結(jié)合的方式實(shí)現(xiàn)的,但因?yàn)樵阡秩竞褪录幚碇幸恍┍容^怪異的行為(感興趣的話可以看下issue),所以最終統(tǒng)一采用了微任務(wù)。

先看第一塊:

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

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

再看第二塊:

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é)點(diǎn),并通過 observer 去觀察文本節(jié)點(diǎn)的變化。 characterData: true 這個配置就是當(dāng)文字變化的時候就會執(zhí)行回調(diào)。(counter + 1) % 2 會使文本節(jié)點(diǎn)的文字在 01 、 0 、 1之間不同變化,這樣就會被 observer 觀察到。MutationObserver 也是微任務(wù)。

然后是第三塊:

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

當(dāng)微任務(wù)都不被支持時,就要使用宏任務(wù)了。其實(shí)大多數(shù)情況下都不會走到這里,因?yàn)?setImmediate 并沒有成為正式的標(biāo)準(zhǔn),并且兼容性很差。

最后是第四塊:

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

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

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

以上就是Vue中$nextTick實(shí)現(xiàn)源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Vue $nextTick解析的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 裝飾者模式在日常開發(fā)中的縮影和vue中的使用詳解

    裝飾者模式在日常開發(fā)中的縮影和vue中的使用詳解

    這篇文章主要為大家介紹了裝飾者模式在日常開發(fā)中的縮影和vue中的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • vue3?+?elementPlus?reset重置表單問題

    vue3?+?elementPlus?reset重置表單問題

    這篇文章主要介紹了vue3?+?elementPlus?reset重置表單問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue前端利用slice()方法實(shí)現(xiàn)分頁器

    Vue前端利用slice()方法實(shí)現(xiàn)分頁器

    分頁功能是常見的需求之一,本文主要介紹了Vue前端利用slice()方法實(shí)現(xiàn)分頁器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Vue 組件復(fù)用多次自定義參數(shù)操作

    Vue 組件復(fù)用多次自定義參數(shù)操作

    這篇文章主要介紹了Vue 組件復(fù)用多次自定義參數(shù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序

    Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序

    在日常開發(fā)中,特別是管理端,經(jīng)常會遇到要實(shí)現(xiàn)拖拽排序的效果,下面這篇文章主要給大家介紹了關(guān)于Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 解決Vue2.0 watch對象屬性變化監(jiān)聽不到的問題

    解決Vue2.0 watch對象屬性變化監(jiān)聽不到的問題

    今天小編就為大家分享一篇解決Vue2.0 watch對象屬性變化監(jiān)聽不到的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 快速理解Vue路由導(dǎo)航守衛(wèi)

    快速理解Vue路由導(dǎo)航守衛(wèi)

    這篇文章主要介紹了快速理解Vue路由導(dǎo)航守衛(wèi),“導(dǎo)航”表示路由正在發(fā)生變化,vue-router?提供的導(dǎo)航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。有多種機(jī)會植入路由導(dǎo)航過程?中:全局的,?單個路由獨(dú)享的,?或者組件級的,下面來快速來接具體內(nèi)容吧
    2021-12-12
  • Vue組件Draggable實(shí)現(xiàn)拖拽功能

    Vue組件Draggable實(shí)現(xiàn)拖拽功能

    這篇文章主要為大家詳細(xì)介紹了Vue組件Draggable實(shí)現(xiàn)拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • vue.js中引入vuex儲存接口數(shù)據(jù)及調(diào)用的詳細(xì)流程

    vue.js中引入vuex儲存接口數(shù)據(jù)及調(diào)用的詳細(xì)流程

    這篇文章主要給大家介紹了關(guān)于在vue.js中引入vuex儲存接口數(shù)據(jù)及調(diào)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • Vue中mapMutations傳遞參數(shù)方式

    Vue中mapMutations傳遞參數(shù)方式

    這篇文章主要介紹了Vue中mapMutations傳遞參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評論