Vue中的$nextTick

?🌈個人主頁:前端青山
🔥系列專欄:Vue篇
🔖人終將被年少不可得之物困其一生

依舊青山,本期給大家帶來vue篇專欄內容:vue中的$nextTick

目錄

🐋Vue中的$nextTick有什么作用?

🐋一、NextTick是什么

為什么要有nexttick

🐋二、使用場景

🐋三、實現原理

?$nextTick()

Vue中的$nextTick有什么作用?

一、NextTick是什么

官方對其的定義

在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM

什么意思呢?

我們可以理解成,Vue 在更新 DOM 時是異步執行的。當數據發生變化,Vue將開啟一個異步更新隊列,視圖需要等隊列中所有數據變化完成之后,再統一進行更新

舉例一下

Html結構

<div id="app"> {{ message }} </div>

構建一個vue實例

const vm = new Vue({el: '#app',data: {message: '原始值'}
})

修改message

this.message = '修改后的值1'
this.message = '修改后的值2'
this.message = '修改后的值3'

這時候想獲取頁面最新的DOM節點,卻發現獲取到的是舊值

console.log(vm.$el.textContent) // 原始值

這是因為message數據在發現變化的時候,vue并不會立刻去更新Dom,而是將修改數據的操作放在了一個異步操作隊列中

如果我們一直修改相同數據,異步操作隊列還會進行去重

等待同一事件循環中的所有數據變化完成之后,會將隊列中的事件拿來進行處理,進行DOM的更新

為什么要有nexttick

舉個例子

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

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

二、使用場景

如果想要在修改數據后立刻得到更新后的DOM結構,可以使用Vue.nextTick()

第一個參數為:回調函數(可以獲取最近的DOM結構)

第二個參數為:執行函數上下文

// 修改數據
vm.message = '修改后的值'
// DOM 還沒有更新
console.log(vm.$el.textContent) // 原始的值
Vue.nextTick(function () {// DOM 更新了console.log(vm.$el.textContent) // 修改后的值
})

組件內使用 vm.$nextTick() 實例方法只需要通過this.$nextTick(),并且回調函數中的 this 將自動綁定到當前的 Vue 實例上

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

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

this.message = '修改后的值'
console.log(this.$el.textContent) // => '原始的值'
await this.$nextTick()
console.log(this.$el.textContent) // => '修改后的值'

三、實現原理

callbacks也就是異步操作隊列

callbacks新增回調函數后又執行了timerFunc函數,pending是用來標識同一個時間只能執行一次

export function nextTick(cb?: Function, ctx?: Object) {let _resolve;
?// cb 回調函數會經統一處理壓入 callbacks 數組callbacks.push(() => {if (cb) {// 給 cb 回調函數執行加上了 try-catch 錯誤處理try {cb.call(ctx);} catch (e) {handleError(e, ctx, 'nextTick');}} else if (_resolve) {_resolve(ctx);}});
?// 執行異步延遲函數 timerFuncif (!pending) {pending = true;timerFunc();}
?// 當 nextTick 沒有傳入函數參數的時候,返回一個 Promise 化的調用if (!cb && typeof Promise !== 'undefined') {return new Promise(resolve => {_resolve = resolve;});}
}

timerFunc函數定義,這里是根據當前環境支持什么方法則確定調用哪個,分別有:

Promise.thenMutationObserversetImmediatesetTimeout

通過上面任意一種方法,進行降級操作

export let isUsingMicroTask = false
if (typeof Promise !== 'undefined' && isNative(Promise)) {//判斷1:是否原生支持Promiseconst 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:是否原生支持MutationObserverlet counter = 1const observer = new MutationObserver(flushCallbacks)const textNode = document.createTextNode(String(counter))observer.observe(textNode, {characterData: true})timerFunc = () => {counter = (counter + 1) % 2textNode.data = String(counter)}isUsingMicroTask = true
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {//判斷3:是否原生支持setImmediatetimerFunc = () => {setImmediate(flushCallbacks)}
} else {//判斷4:上面都不行,直接用setTimeouttimerFunc = () => {setTimeout(flushCallbacks, 0)}
}

無論是微任務還是宏任務,都會放到flushCallbacks使用

這里將callbacks里面的函數復制一份,同時callbacks置空

依次執行callbacks里面的函數

function flushCallbacks () {pending = falseconst copies = callbacks.slice(0)callbacks.length = 0for (let i = 0; i < copies.length; i++) {copies[i]()}
}

?$nextTick()

綁定在實例上的 nextTick() 函數。

和全局版本的 nextTick() 的唯一區別就是組件傳遞給 this.$nextTick() 的回調函數會帶上 this 上下文,其綁定了當前組件實例。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>nextTick</title>
</head>
<body><div id="app"><div ref="oDiv">{{ count }}</div><button @click="add">加1</button></div>
</body>
<script src="../lib/vue.global.js"></script>
<script>Vue.createApp({data () {return {count: 10}},methods: {add () {this.count++console.log(1, this.count) // 11// 獲取dom節點真實的值console.log(2, this.$refs.oDiv.innerHTML) // 10
?// 借助于 nextTick 函數 獲取真實的DOM的值// 上啦加載 - 滾動條滾動到一定距離,加載數據// 瀑布流布局時,實時獲取每一列的高度,將下一個數據插入到高度最低的那一列this.$nextTick(() => {console.log(3, this.$refs.oDiv.innerHTML) // 11})}}}).mount('#app')
</script>
</html>

小結:

  1. 把回調函數放入callbacks等待執行

  2. 將執行函數放到微任務或者宏任務中

  3. 事件循環到了微任務或者宏任務,執行函數依次執行callbacks中的回調

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167405.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167405.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167405.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

socket can中是如何根據 結構體can_bittiming_const中的字段 計算bitrate的?

在 SocketCAN 中&#xff0c;can_bittiming_const 結構體用于表示 CAN 總線的定時參數&#xff0c;包括位率&#xff08;bitrate&#xff09;的計算。can_bittiming_const 包含了許多與位率相關的參數&#xff0c;其中一些參數用于計算實際的位率。 下面是一些與位率計算相關的…

小辰的智慧樹(差分+前綴和)

登錄—專業IT筆試面試備考平臺_牛客網 1.考慮總長度之和不能超過m&#xff0c;2考慮限制每棵樹高度不能低于ci&#xff0c;如果用二分最短輸能截到的高度&#xff0c;還要另外去判斷&#xff0c;是否每棵樹mid都能嚴格大于ci &#xff0c;這樣容易超時&#xff0c;換個角度&…

SQL常見函數整理 _ lead() 向下偏移

1. 用法 是在窗口函數中使用的函數&#xff0c;它用于獲取當前行的下一行&#xff08;后一行&#xff09;的某個列的值。具體來說&#xff0c;LEAD() 函數可用于查找任何給定行的下一行&#xff08;后一行&#xff09;的值&#xff0c;同時也可控制行數偏移量&#xff08;offse…

競賽選題 題目:基于LSTM的預測算法 - 股票預測 天氣預測 房價預測

文章目錄 0 簡介1 基于 Keras 用 LSTM 網絡做時間序列預測2 長短記憶網絡3 LSTM 網絡結構和原理3.1 LSTM核心思想3.2 遺忘門3.3 輸入門3.4 輸出門 4 基于LSTM的天氣預測4.1 數據集4.2 預測示例 5 基于LSTM的股票價格預測5.1 數據集5.2 實現代碼 6 lstm 預測航空旅客數目數據集預…

社交媒體廣告數據采集:Jsoup 的最佳實踐

搜狐是中國領先的綜合門戶網站之一&#xff0c;廣告在其網站上廣泛投放。為了了解搜狐廣告的策略和趨勢&#xff0c;采集和分析搜狐廣告數據變得至關重要。但是&#xff0c;搜狐網站的廣告數據通常需要通過網頁抓取的方式獲取&#xff0c;這就需要一個強大的工具來解析和提取數…

面試:線上問題處理

文章目錄 在處理線上問題時&#xff0c;你的排查思路和步驟是什么線上偶發性問題如何處理和跟蹤當系統出現大量錯誤日志時&#xff0c;你會如何分析和解決問題在高并發場景中&#xff0c;如何排查和解決線程安全問題當系統出現大規模的故障時&#xff0c;你的應急處理和恢復策略…

用友BIP與用友BIP對接集成銷售出庫列表查詢連通銷售出庫單個保存((紅字)銷售出庫審核-v)

用友BIP與用友BIP對接集成銷售出庫列表查詢連通銷售出庫單個保存(&#xff08;紅字&#xff09;銷售出庫審核-v) 源系統:用友BIP 面向數智化市場&#xff0c;用友傾力打造了全球領先的數智商業創新平臺——用友BIP&#xff0c;定位為數智商業的應用級基礎設施、企業服務產業的共…

虛擬機系列:(VMware Workstation Pro)Centos7下搭建Android開發環境及Android真機調試

一、Android SDK 安裝配置 1、環境 Linux系統為:Red Hat Enterprise Linux 7 64 位 ; 當然還需要Java環境,java 環境這里不敘述; 2、Android Studio 安裝 (1)下載位置: http://www.android-studio.org/ 我這里下載的:android-studio-ide-191.5977832-linux.tar.gz …

pat實現基于鄰接矩陣表示的深度優先遍歷

void DFS(Graph G, int v) {visited[v] 1;printf("%c ", G.vexs[v]);for (int i 0; i < G.vexnum; i) {if (!visited[i] && G.arcs[v][i]) DFS(G, i);} }

SpectralGPT: Spectral Foundation Model 論文翻譯2

遙感領域的通用大模型 2023.11.13在CVPR發表 原文地址&#xff1a;[2311.07113] SpectralGPT: Spectral Foundation Model (arxiv.org) 實驗 ? 在本節中&#xff0c;我們將嚴格評估我們的SpectralGPT模型的性能&#xff0c;并對其進行基準測試SOTA基礎模型&#xff1a;ResN…

kubernetesr進階--Security Context之為容器設置Security Context

容器的定義中包含 securityContext 字段&#xff0c;該字段接受 SecurityContext 對象。通過指定該字段&#xff0c;可以為容器設定安全相關的配置&#xff0c;當該字段的配置與 Pod 級別的 securityContext 配置相沖突時&#xff0c;容器級別的配置將覆蓋 Pod 級別的配置。容器…

03.依賴倒置原則(Dependence Inversion Principle)

概述 高層模塊不應依賴低層模塊&#xff0c;二者都應該依賴其抽象。而抽象不應依賴細節&#xff0c;細節應該依賴抽象。依賴倒置原則的中心思想其實就是面向接口編程。 相對于細節的多變性&#xff0c;抽象的東西會穩定的多&#xff0c;所以以抽象為基礎搭建的架構自然也會比以…

EMG肌肉電信號處理合集(二)

本文主要展示常見的肌電信號特征的提取說明。使用python 環境下的Pysiology計算庫。 目錄 1 肌電信號第一次burst的振幅&#xff0c; getAFP 函數 2 肌電信號波長的標準差計算&#xff0c;getDASDV函數 3 肌電信號功率譜頻率比例&#xff0c;getFR函數 4 肌電信號直方圖…

Day41:198.打家劫舍、213.打家劫舍II、337.打家劫舍 III

文章目錄 198.打家劫舍思路代碼實現 213.打家劫舍II思路代碼實現 337.打家劫舍 III思路代碼實現記憶化遞歸法&#xff08;其他解法&#xff09; 198.打家劫舍 題目鏈接 思路 確定dp數組&#xff08;dp table&#xff09;以及下標的含義 dp[i]&#xff1a;考慮下標i以內的房屋…

華清遠見嵌入式學習——網絡編程——小項目

項目要求&#xff1a; 代碼實現&#xff1a; 服務器端&#xff1a; #include <myhead.h>//定義協議包 struct proto {char type;char name[20];char text[128]; };int main(int argc, const char *argv[]) {//判斷從終端輸入的字符串的個數if(argc ! 3){printf("…

mysql中TIMESTAMP 和DATETIME數據類型的區別

在MySQL中&#xff0c;TIMESTAMP和DATETIME都用于表示日期和時間&#xff0c;但是它們之間存在一些關鍵區別。下面我們通過幾個關鍵點來詳細了解這兩種數據類型的使用&#xff1a; 存儲范圍 TIMESTAMP類型的存儲范圍從1970-01-01 00:00:01 UTC到2038-01-19 03:14:07 UTC。DAT…

Django之importlib模塊

【1】介紹 import importlib importlib模塊是Python中用于動態加載和導入模塊的內置模塊 它提供了一組函數和類&#xff0c;使得我們可以在運行時根據需要加載模塊&#xff0c;并且可以對已導入的模塊進行操作和管理 【2】importlib模塊中的import_module方法 【2.1】導入模塊…

無需API開發,錢方QFPay連接營銷系統和廣告推廣平臺

隨著電子商務市場的不斷發展&#xff0c;企業需要集成各種業務系統&#xff0c;以提高業務效率和降低運營成本。錢方QFPay提供了一種創新的解決方案&#xff0c;幫助企業實現系統間的連接和集成&#xff0c;無需進行復雜的API開發。除了電商系統和客服系統&#xff0c;錢方還能…

武漢光庭公司地圖引擎開發工程師24秋招三場面試完整流程

本文介紹2024屆秋招中&#xff0c;武漢光庭信息技術股份有限公司的智能駕駛地圖引擎開發工程師崗位一面、二面、三面的面試基本情況、提問問題等。 10月投遞了武漢光庭信息技術股份有限公司的智能駕駛地圖引擎開發工程師崗位&#xff0c;暫時并不清楚所在的部門。目前完成了全部…

mysql:修改密碼的幾種方式

背景 當我們 brew install mysql 新安裝 mysql 的時候&#xff0c;是沒有密碼的&#xff0c;我們可以直接通過 mysql -u root 連接上。但是密碼還是要設置的&#xff0c;一是為了安全&#xff0c;二是有些數據庫軟件如 Sequel 連接都是必須要密碼的&#xff0c;接下來我們來看…