溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue中nexttick的原理是什么

發(fā)布時間:2020-07-02 13:50:17 來源:億速云 閱讀:438 作者:元一 欄目:web開發(fā)

vue中nexttick的原理是什么?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Vue.nextTick是Vue官方給我們提供的一個API(方法),作用是在下次DOM更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的DOM;

當(dāng)數(shù)據(jù)發(fā)生變化之后,DOM視圖并不會立即更新,如果我們在發(fā)生變化之后立馬去獲取某個節(jié)點或者某個節(jié)點的值,很有可能結(jié)果就是undefined;因為Vue實現(xiàn)響應(yīng)式并不是數(shù)據(jù)發(fā)生變化之后DOM立即變化,而是按一定的策略進行DOM的更新。

一、原理

1.異步說明

Vue 實現(xiàn)響應(yīng)式并不是數(shù)據(jù)發(fā)生變化之后 DOM 立即變化,而是按一定的策略進行 DOM 的更新。

2.事件循環(huán)說明

簡單來說,Vue在修改數(shù)據(jù)后,視圖不會立刻更新,而是等同一事件循環(huán)中的所有數(shù)據(jù)變化完成之后,再統(tǒng)一進行視圖更新。

eg:

vue中nexttick的原理是什么

圖解:

vue中nexttick的原理是什么

事件循環(huán):

第一個tick(本次更新循環(huán))

1.首先修改數(shù)據(jù),這是同步任務(wù)。同一事件循環(huán)的所有的同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧,此時還未涉及DOM.

2.Vue開啟一個異步隊列,并緩沖在此事件循環(huán)中發(fā)生的所有數(shù)據(jù)變化。如果同一個watcher被多次觸發(fā),只會被推入隊列中一次。

第二個tick(‘下次更新循環(huán)’)

同步任務(wù)執(zhí)行完畢,開始執(zhí)行異步watcher隊列的任務(wù),更新DOM。Vue在內(nèi)部嘗試對異步隊列使用原生的Promise.then和MessageChannel 方法,如果執(zhí)行環(huán)境不支持,會采用 setTimeout(fn, 0) 代替。

第三個tick(下次 DOM 更新循環(huán)結(jié)束之后)

二、應(yīng)用場景及原因

1.

  • 在Vue生命周期的created()鉤子函數(shù)進行的DOM操作一定要放在Vue.nextTick()的回調(diào)函數(shù)中

在created()鉤子函數(shù)執(zhí)行的時候DOM 其實并未進行任何渲染,而此時進行DOM操作無異于徒勞,所以此處一定要將DOM操作的js代碼放進Vue.nextTick()的回調(diào)函數(shù)中。與之對應(yīng)的就是mounted()鉤子函數(shù),因為該鉤子函數(shù)執(zhí)行時所有的DOM掛載和渲染都已完成,此時在該鉤子函數(shù)中進行任何DOM操作都不會有問題 。

  • 在數(shù)據(jù)變化后要執(zhí)行的某個操作,而這個操作需要使用隨數(shù)據(jù)改變而改變的DOM結(jié)構(gòu)的時候,這個操作都應(yīng)該放進Vue.nextTick()的回調(diào)函數(shù)中。
2.在數(shù)據(jù)變化后要執(zhí)行的某個操作,而這個操作需要使用隨數(shù)據(jù)改變而改變的DOM結(jié)構(gòu)的時候,這個操作都應(yīng)該放進Vue.nextTick()的回調(diào)函數(shù)中。

具體原因在Vue的官方文檔中詳細(xì)解釋:

Vue 異步執(zhí)行 DOM 更新。只要觀察到數(shù)據(jù)變化,Vue 將開啟一個隊列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)改變。如果同一個 watcher 被多次觸發(fā),只會被推入到隊列中一次。這種在緩沖時去除重復(fù)數(shù)據(jù)對于避免不必要的計算和 DOM 操作上非常重要。然后,在下一個的事件循環(huán)“tick”中,Vue 刷新隊列并執(zhí)行實際 (已去重的) 工作。Vue 在內(nèi)部嘗試對異步隊列使用原生的Promise.then和MessageChannel,如果執(zhí)行環(huán)境不支持,會采用setTimeout(fn, 0)代替。

例如,當(dāng)你設(shè)置vm.someData = 'new value',該組件不會立即重新渲染。當(dāng)刷新隊列時,組件會在事件循環(huán)隊列清空時的下一個“tick”更新。多數(shù)情況我們不需要關(guān)心這個過程,但是如果你想在 DOM 狀態(tài)更新后做點什么,這就可能會有些棘手。雖然 Vue.js 通常鼓勵開發(fā)人員沿著“數(shù)據(jù)驅(qū)動”的方式思考,避免直接接觸 DOM,但是有時我們確實要這么做。為了在數(shù)據(jù)變化之后等待 Vue 完成更新 DOM ,可以在數(shù)據(jù)變化之后立即使用Vue.nextTick(callback)。這樣回調(diào)函數(shù)在 DOM 更新完成后就會調(diào)用。

關(guān)于vue中nexttick的原理是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI