中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Vue.$nextTick的原理是什么

發布時間:2023-03-02 09:12:58 來源:億速云 閱讀:116 作者:iii 欄目:編程語言

這篇文章主要介紹了Vue.$nextTick的原理是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Vue.$nextTick的原理是什么文章都會有所收獲,下面我們一起來看看吧。

Vue中DOM更新機制

當你氣勢洶洶地使用Vue大展宏圖的時候,突然發現,咦,我明明對這個數據進行更改了,但是當我獲取它的時候怎么是上一次的值(本人比較懶,就不具體舉例了?)

此時,Vue就會說:“小樣,這你就不懂了吧,我的DOM是異步更新的呀!!!”

簡單的說,Vue的響應式并不是只數據發生變化之后,DOM就立刻發生變化,而是按照一定的策略進行DOM的更新。這樣的好處是可以避免一些對DOM不必要的操作,提高渲染性能。

在Vue官方文檔中是這樣說明的:

可能你還沒有注意到,Vue異步執行DOM更新。只要觀察到數據變化,Vue將開啟一個隊列,并緩沖在同一事件循環中發生的所有數據改變。如果同一個watcher被多次觸發,只會被推入到隊列中一次。這種在緩沖時去除重復數據對于避免不必要的計算和DOM操作上非常重要。然后,在下一個的事件循環“tick”中,Vue刷新隊列并執行實際 (已去重的) 工作。

白話一點就是說,其實這是和JS當中的事件循環是息息相關的,就是Vue不可能對每一個數據變化都做一次渲染,它會把這些變化先放在一個異步的隊列當中,同時它還會對這個隊列里面的操作進行去重,比如你修改了這個數據三次,它只會保留最后一次。這些變化是都可以通過隊列的形式保存起來,那現在的問題就來到了,那vue是在事件循環的哪個時機來對DOM進行修改呢?

Vue有兩種選擇,一個是在本次事件循環的最后進行一次DOM更新,另一種是把DOM更新放在下一輪的事件循環當中。z這時,尤雨溪拍了拍胸脯說:“這兩種方法,我都有!” 但是因為本輪事件循環最后執行會比放在下一輪事件循環要快很多,所以Vue優先選擇第一種,只有當環境不支持的時候才觸發第二種機制。(??開頭的鏈接讓你懂事件循環)

雖然性能上提高了很多,但這個時候問題就出現了,我們都知道在一輪事件循環中,同步執行棧中代碼執行完成之后,才會執行異步隊列當中的內容,那我們獲取DOM的操作是一個同步的呀!!那豈不是雖然我已經把數據改掉了,但是它的更新異步的,而我在獲取的時候,它還沒有來得及改,所以會出現文章開頭的那個問題。

這。。。我確實需要進行這樣操作,那這么辦呢??

沒關系啦,尤大很貼心的為我們提供了Vue.$nextTick()

Vue.$nextTick()

其實一句話就可以把$nextTick這個東西講明白:就是你放在$nextTick 當中的操作不會立即執行,而是等數據更新、DOM更新完成之后再執行,這樣我們拿到的肯定就是最新的了。

再準確一點來講就是$nextTick方法將回調延遲到下次DOM更新循環之后執行。(看不懂這句人話的,可以看上面[狗頭])

意思我們都懂了,那$nextTick是怎樣完成這個神奇的功能的呢? 核心如下:

Vue在內部對異步隊列嘗試使用原生的Promise.thenMutationObserversetImmediate,如果執行環境不支持,則會采用 setTimeout(fn, 0)代替。

仔細地看這句話,你就可以發現這不就是利用 JavaScript 的這些異步回調任務隊列,來實現 Vue 框架中自己的異步回調隊列。這其實就是一個典型的將底層 JavaScript 執行原理應用到具體案例中的示例。

我在這里稍微總結一下:就是$nextTick將回調函數放到微任務或者宏任務當中以延遲它地執行順序;(總結的也比較懶?)

重要的是理解源碼中它的三個參數的意思:

  • callback:我們要執行的操作,可以放在這個函數當中,我們沒執行一次$nextTick就會把回調函數放到一個異步隊列當中;

  • pending:標識,用以判斷在某個事件循環中是否為第一次加入,第一次加入的時候才觸發異步執行的隊列掛載

  • timerFunc:用來觸發執行回調函數,也就是Promise.thenMutationObserversetImmediatesetTimeout的過程

理解之后,在看整個$nextTick里面的執行過程,其實就是把一個個$nextTick中的回調函數壓入到callback隊列當中,然后根據事件的性質等待執行,輪到它執行的時候,就執行一下,然后去掉callback隊列中相應的事件。

使用

說了這么多,怎么用它呢? 很簡單很簡單

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

使用場景

  • created中獲取DOM的操作需要使用它

  • 就是我們上面的例子,你如果想要獲取最新值,就用它

  • 還有一些第三方插件使用過程中,使用到的情況,具體問題具體分析

補充

之前我一直搞不懂一個的問題,$nextTick既然把它傳入的方法變成微任務了,那它和其它微任務的執行順序是怎樣的呢?

這簡單來說就是誰先掛載Promise對象的問題,在調用$nextTick方法時就會將其閉包內部維護的執行隊列掛載到Promise對象,在數據更新時Vue內部首先就會執行$nextTick方法,之后便將執行隊列掛載到了Promise對象上,其實在明白JsEvent Loop模型后,將數據更新也看做一個$nextTick方法的調用,并且明白$nextTick方法會一次性執行所有推入的回調,就可以明白執行順序的問題了

還有$nextTicknextTick區別就是nextTick多了一個context參數,用來指定上下文。但兩個的本質是一樣的,$nextTick是實例方法,nextTick是類的靜態方法而已;實例方法的一個好處就是,自動給你綁定為調用實例的this罷了。

關于“Vue.$nextTick的原理是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Vue.$nextTick的原理是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

融水| 金乡县| 龙海市| 当涂县| 庆云县| 行唐县| 梓潼县| 盐亭县| 宜兴市| 屯昌县| 扶风县| 郸城县| 镇赉县| 道孚县| 大方县| 台湾省| 长治县| 灯塔市| 丹江口市| 蓬安县| 曲松县| 柞水县| 寻甸| 尖扎县| 镇雄县| 大邑县| 五华县| 岳西县| 涿鹿县| 仲巴县| 定远县| 正蓝旗| 青川县| 大化| 将乐县| 门头沟区| 甘洛县| 苍南县| 宣汉县| 勃利县| 沅陵县|