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

Vue NextTick介紹與使用原理

 更新時(shí)間:2022年08月05日 10:34:04   作者:飯啊飯°  
我們對(duì)Vue中data數(shù)據(jù)的修改會(huì)導(dǎo)致界面對(duì)應(yīng)的響應(yīng)變化,而通過nextTick方法,可以在傳入nextTick的回調(diào)函數(shù)中獲取到變化后的DOM,講起來可能還是有點(diǎn)夢(mèng)幻,下面我們直接使用nextTick體驗(yàn)一下效果

一、NextTick是什么

定義

在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。

理解

Vue在更新DOM時(shí)時(shí)異步執(zhí)行的。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),Vue將開啟一個(gè)異步更新隊(duì)列,視圖需要等隊(duì)列中所有數(shù)據(jù)變化完成之后,再統(tǒng)一進(jìn)行更新。

舉例:

<body>
    <div id="app">
        <div>
            <button id="firstBtn" @click="testClick()" ref="aa">{{testMsg}}</button>
          </div>
    </div>
</body>
</html>
<script>
    new Vue({
        el:'#app',
        data () {
    return {
      testMsg:"原始值",
    }
  },
  methods:{
    testClick:function(){
      this.testMsg="修改后的值";
      console.log(this.$refs.aa.innerText);   //that.$refs.aa獲取指定DOM,輸出:原始值
      console.log(document.querySelector('#firstBtn').innerText)
    }
  }
})
</script>

這時(shí)候想獲取頁面最新的DOM節(jié)點(diǎn),卻發(fā)現(xiàn)獲取到的仍然是舊值。

這是因?yàn)閙essage數(shù)據(jù)在發(fā)現(xiàn)變化的時(shí)候,vue并不會(huì)立刻去更新Dom,而是將修改數(shù)據(jù)的操作放在了一個(gè)異步操作隊(duì)列中,如果我們一直修改相同數(shù)據(jù),異步操作隊(duì)列還會(huì)進(jìn)行去重,等待同一事件循環(huán)中的所有數(shù)據(jù)變化完成之后,會(huì)將隊(duì)列中的事件拿來進(jìn)行處理,進(jìn)行DOM的更新。

為什么要有nexttick

{{num}}
for(let i=0; i<100000; i++){
    num = i
}

如果沒有 nextTick 更新機(jī)制,那么 num 每次更新值都會(huì)觸發(fā)視圖更新(上面這段代碼也就是會(huì)更新10萬次視圖),有了nextTick機(jī)制,只需要更新一次,所以nextTick本質(zhì)是一種優(yōu)化策略。

二、使用場(chǎng)景

this.testMsg="修改后的值";
console.log(this.$refs.aa.innerText);   //that.$refs.aa獲取指定DOM,輸出:原始值
Vue.nextTick(function(){
  console.log(document.querySelector('#firstBtn').innerText)
})

組件內(nèi)使用vm.$nextTick() 實(shí)例方法只需要通過this. $nextTick(),并且回調(diào)函數(shù)中的 this 將自動(dòng)綁定到當(dāng)前的 Vue 實(shí)例上

this.message = '修改后的值'
console.log(this.$refs.aa.innerText) // => '原始的值'
this.$nextTick(function () {
    console.log(this.$refs.aa.innerText) // => '修改后的值'
})

$nextTick() 會(huì)返回一個(gè) Promise 對(duì)象,可以是用async/await完成相同作用的事情

await Vue.nextTick()
console.log(document.querySelector('#firstBtn').innerText)

三、實(shí)現(xiàn)原理

  • callbacks也就是異步操作隊(duì)列
  • callbacks新增回調(diào)函數(shù)后又執(zhí)行了timerFunc函數(shù),pending是用來標(biāo)識(shí)同一個(gè)時(shí)間只能執(zhí)行一次。
export function nextTick(cb?: Function, ctx?: Object) {
  let _resolve;
  // cb 回調(diào)函數(shù)會(huì)經(jīng)統(tǒng)一處理壓入 callbacks 數(shù)組
  callbacks.push(() => {
    if (cb) {
      // 給 cb 回調(diào)函數(shù)執(zhí)行加上了 try-catch 錯(cuò)誤處理
      try {
        cb.call(ctx);
      } catch (e) {
        handleError(e, ctx, 'nextTick');
      }
    } else if (_resolve) {
      _resolve(ctx);
    }
  });
  // 執(zhí)行異步延遲函數(shù) timerFunc
  if (!pending) {
    pending = true;
    timerFunc();
  }
  // 當(dāng) nextTick 沒有傳入函數(shù)參數(shù)的時(shí)候,返回一個(gè) Promise 化的調(diào)用
  if (!cb && typeof Promise !== 'undefined') {
    return new Promise(resolve => {
      _resolve = resolve;
    });
  }
}
  • timerFunc函數(shù)定義,這里是根據(jù)當(dāng)前環(huán)境支持什么方法則確定調(diào)用哪個(gè),分別有:Promise.then、MutationObserver、setImmediate、setTimeout;
  • 通過上面任意一種方法,進(jìn)行降級(jí)操作
export let isUsingMicroTask = false
if (typeof Promise !== 'undefined' && isNative(Promise)) {
  //判斷1:是否原生支持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]'
)) {
  //判斷2:是否原生支持MutationObserver
  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)) {
  //判斷3:是否原生支持setImmediate
  timerFunc = () => {
    setImmediate(flushCallbacks)
  }
} else {
  //判斷4:上面都不行,直接用setTimeout
  timerFunc = () => {
    setTimeout(flushCallbacks, 0)
  }
}
  • 無論是微任務(wù)還是宏任務(wù),都會(huì)放到flushCallbacks使用
  • 這里將callbacks里面的函數(shù)復(fù)制一份,同時(shí)callbacks置空
  • 依次執(zhí)行callbacks里面的函數(shù)
function flushCallbacks () {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

小結(jié):

  • 把回調(diào)函數(shù)放入callbacks等待執(zhí)行;
  • 將執(zhí)行函數(shù)放到微任務(wù)或者宏任務(wù)中;
  • 事件循環(huán)到了微任務(wù)或者宏任務(wù),執(zhí)行函數(shù)依次執(zhí)行callbacks中的回調(diào)。

到此這篇關(guān)于Vue NextTick介紹與使用原理的文章就介紹到這了,更多相關(guān)Vue NextTick內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue?日期獲取的示例代碼

    Vue?日期獲取的示例代碼

    moment.js是一款現(xiàn)在對(duì)時(shí)間處理的強(qiáng)大的函數(shù),這篇文章主要介紹了Vue?日期獲取的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • vue在自定義組件上使用v-model和.sync的方法實(shí)例

    vue在自定義組件上使用v-model和.sync的方法實(shí)例

    自定義組件的v-model和.sync修飾符其實(shí)本質(zhì)上都是vue的語法糖,用于實(shí)現(xiàn)父子組件的"數(shù)據(jù)"雙向綁定,下面這篇文章主要給大家介紹了關(guān)于vue在自定義組件上使用v-model和.sync的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • vue.js父子組件通信動(dòng)態(tài)綁定的實(shí)例

    vue.js父子組件通信動(dòng)態(tài)綁定的實(shí)例

    今天小編就為大家分享一篇vue.js父子組件通信動(dòng)態(tài)綁定的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 利用Vite2和Vue3實(shí)現(xiàn)網(wǎng)站國(guó)際化的全過程

    利用Vite2和Vue3實(shí)現(xiàn)網(wǎng)站國(guó)際化的全過程

    vite2已經(jīng)出來一段時(shí)間了,最近沒忍住嘗試了一下,這篇文章主要給大家介紹了關(guān)于利用Vite2和Vue3實(shí)現(xiàn)網(wǎng)站國(guó)際化的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • vuex Module將 store 分割成模塊的操作

    vuex Module將 store 分割成模塊的操作

    這篇文章主要介紹了vuex Module將 store 分割成模塊,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • vue-router傳參的四種方式超詳細(xì)講解

    vue-router傳參的四種方式超詳細(xì)講解

    這篇文章主要介紹了vue-router傳參的四種方式超詳細(xì),有router-link路由導(dǎo)航方式傳參,調(diào)用$router.push實(shí)現(xiàn)路由傳參,通過路由屬性name匹配路由,再根據(jù)params傳遞參數(shù)等等,結(jié)合示例代碼講解的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 詳解Vue監(jiān)聽數(shù)據(jù)變化原理

    詳解Vue監(jiān)聽數(shù)據(jù)變化原理

    本篇文章主要介紹了Vue監(jiān)聽數(shù)據(jù)變化,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • Vue實(shí)現(xiàn)購(gòu)物車基本功能

    Vue實(shí)現(xiàn)購(gòu)物車基本功能

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)購(gòu)物車的基本功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • vue3如何監(jiān)聽頁面的滾動(dòng)

    vue3如何監(jiān)聽頁面的滾動(dòng)

    這篇文章主要給大家介紹了關(guān)于vue3如何監(jiān)聽頁面的滾動(dòng)的相關(guān)資料,在vue中實(shí)現(xiàn)滾動(dòng)監(jiān)聽和原生js無太大差異,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • vue3.0 proxy設(shè)置代理不成功的問題及解決方案

    vue3.0 proxy設(shè)置代理不成功的問題及解決方案

    這篇文章主要介紹了vue3.0 proxy設(shè)置代理不成功的問題及解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12

最新評(píng)論