Vue的nextTick是什麼?

2022-08-05 08:57:13 字數 2753 閱讀 3175

公司做之前專案的時候,遇到了一些比較困惑的問題,後來研究明白了nexttick的用法。

我們先看兩種情況:

第一種:

export default

},mounted () ,

watch:

}}

這段指令碼執行我們猜測會依次列印:1、2、3。但是實際效果中,只會輸出一次:3。為什麼會出現這樣的情況?

原因:當觸發update更新的時候,會去執行queuewatcher方法,也就是說,下乙個迴圈開始時呼叫,此時msg已經變成3了。

保證更新檢視操作dom的動作是在當前棧執行完以後下乙個tick(或者是當前tick的微任務階段)的時候呼叫,大大優化了效能。

第二種情況:

隨便給了點樣式之後,頁面是這樣的:

看起來似乎一切正常,我們在給陣列新增了一條資料之後,頁面也確實對應的更新了。可是,當我們在列印這個 ul 元素裡 li 的 length 時,問題出現了:

這時候如果我們有需求需要通過 li 的個數來計算出 ul 容器的高度來進行布局,顯然就有問題了。

而這時候 vue 的 nexttick 就可以幫助我們解決這個問題:

關於 vue 的非同步更新佇列,官網是這麼說的:

當你設定 vm.somedata = 'new value' ,該元件不會立即重新渲染。當重新整理佇列時,元件會在事件迴圈佇列清空時的下乙個「tick」更新。多數情況我們不需要關心這個過程,但是如果你想在 dom 狀態更新後做點什麼,這就可能會有些棘手。雖然 vue.js 通常鼓勵開發人員沿著「資料驅動」的方式思考,避免直接接觸 dom,但是有時我們確實要這麼做。為了在資料變化之後等待 vue 完成更新 dom ,可以在資料變化之後立即使用 vue.nexttick(callback) 。這樣**函式在 dom 更新完成後就會呼叫。

簡單說,因為 dom 至少會在當前執行緒裡面的**全部執行完畢再更新。所以不可能做到在修改資料後並且 dom 更新後再執行,要保證在 dom 更新以後再執行某一塊**,就必須把這塊**放到下一次事件迴圈裡面,比如 settimeout(fn, 0),這樣 dom 更新後,就會立即執行這塊**。

我們都知道,js 執行的所有任務都需要排隊,乙個任務必須要等它前面的乙個任務執行完之後才能執行。如果前乙個任務需要花費大量的時間來計算,那麼後乙個任務就必須一直等它執行完才會輪到它執行,這就是單執行緒的特性。 而 js 的任務分為兩種,同步任務和非同步任務:

用乙個醜但易懂的圖來表示:

所以結果輸出是這樣就很好理解了:

被稱作事件迴圈的原因在於,同步的任務可能會生成新的任務,因此它一直在不停的查詢新的事件並執行。一次迴圈的執行稱之為 tick,在這個迴圈裡執行的**被稱作 task,而整個過程是不斷重複的。

console.log(1);

settimeout(()=>,1000);

while (true){}

上面**在輸出 1 之後(謹慎使用!我的瀏覽器就被卡死了~),定時器被塞到任務佇列裡,然後主線程繼續往下執行,碰到乙個死迴圈,導致任務佇列裡的任務永遠不會被執行,因此不會輸出 2

除了我們的主線程之外,任務佇列分為microtaskmacrotask,通常我們會稱之為微任務和巨集任務。microtask這一名詞在js中是個比較新的概念,我們通常是在學習 es6 的promise時才初次接觸到。

console.log(1)

settimeout(

function

())promise.resolve().then(

function

()).then(

function

())console.log(4)

根據執行順序,上面**的輸出結果很容易就能得出了:

讓我們回到上面的主題,vue 的 nexttick方法,

從 原始碼

不難發現,vue 在內部嘗試對非同步佇列使用原生的setimmediatemessagechannel和promise.then

如果當前執行環境不支援,就採用settimeout(fn, 0)代替。

什麼時候需要用vue.nexttick():

mounted: function

() )

}

vue的nextTick的實現

vue的nexttick是用瀏覽器支援的方法模擬nodejs的process.nexttick 老版本的vue用如下方法來模擬 promise.then mutationobserver mutationobserver由於相容性原因被下課 settimeout fn,0 新版本的vue用如下方法來...

Vue裡的nextTick方法

官方解釋 在下次 dom 更新迴圈結束之後執行延遲 在修改資料之後立即使用這個方法,獲取更新後的 dom。自己總結 vue.nexttick callback 當資料發生變化,更新後執行 vue.nexttick callback 當dom發生變化,更新後執行的 例項 message got out...

聊聊VUE中的nextTick

在談nexttick之前,先要說明一件事,可能在我們平時使用vue時並沒有關注到,事實上,vue執行的dom更新是非同步的。舉個栗子 此時控制台列印的是數值是0 這時候如果你將 改一下 這時,控制台列印的數值為1000 這也就說明,vue的dom更新是非同步的,官網上是這樣描述的 可能你還沒有注意到...