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

溫馨提示×

溫馨提示×

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

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

Vue的this.$nextTick怎么使用

發布時間:2022-12-27 11:01:50 來源:億速云 閱讀:143 作者:iii 欄目:編程語言

這篇“Vue的this.$nextTick怎么使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Vue的this.$nextTick怎么使用”文章吧。

nextTick:在下一次DOM更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的DOM。它有兩個參數:第一個參數是回調函數,不傳時提供promise調用;第二個參數是執行環境上下文,不傳默認是自動綁定到調用它的實例上。

我們先看看nextTick究竟是個啥?

console.log(this.$nextTick);
// 控制臺打印
if(fn){
  return nextTick(fn, this);
}

我們可以看出nextTick就是一個方法,方法有兩個參數:fn和this,fn就是需要傳的回調函數,this就是所說的執行環境上下文。那么問題來了,在Vue中是如何實現在下一次DOM更新結束之后才會執行延遲回調的? 我們先看看下面的例子:

<div ref="test1">created:{{message}}</div>
// vue實例
data: {
    message: "Hello World!",
},
created(){
    this.message = '你好,世界!';
    console.log(this.$refs.test1.innerText);// 報錯
    // TypeError: Cannot read properties of undefined (reading 'innerText')
    this.$nextTick(()=>{
         console.log('test1 nextTick:',this.$refs.test1.innerText);// 你好,世界!
    });
},

從上面例子中,在created生命周期中操作了DOM,但是我們都知道created生命周期只是初始化了數據,這期間是還沒有渲染DOM的,如果我們直接操作DOM是找不到DOM元素的,那么問題來了:為什么放在nextTick中就可以獲取到了DOM元素呢? 這不是很明顯嗎,等到DOM渲染完才調用不就獲取到了嗎,從而知道了nextTick作用就是用來等下次DOM渲染完才去調用nextTick內的DOM操作代碼。那么問題又來了,nextTick究竟做了什么?下面我們一起從源碼層面來分別分析Vue2和Vue3版本的nextTick原理是啥。

Vue2版本的nextTick

由于Vue暴露給開發者的是nextTick這個方法,在這個方法中主要做了三件事,回調函數的添加延遲執行回調函數判斷當前的nextTick是否傳入回調函數。不傳的話,是一個Promise,this.$nextTick.then(()=>{}),按Promise處理。

Vue的this.$nextTick怎么使用

  • 回調函數添加入callbacks數組,因為可能有多個nextTick函數在當前作用域中。

Vue的this.$nextTick怎么使用

  • 判斷當前nextTick是否已經標記為pending=true,也就是正在執行,如果不是就執行timerFunc(異步執行函數 用于異步延遲調用 flushCallbacks 函數)。timerFunc的執行,判斷當前環境是否支持promise、MutationObserver、setImmediate、setTimeout,優先級高低從前到后,分四種情況:

  • 優先使用Promise,如果當前環境支持promise,nextTick默認優先使用promise去執行延遲回調函數,timerFunc執行的是Promise,promise是es6下的語法,如果當前環境只支持es6以語法下的,只能考慮后面支持情況了。

Vue的this.$nextTick怎么使用

  • 支持MutationObserver,HTML5的api,中文意思是:修改的監聽,MutationObserver用來監聽DOM的變動,比如節點的增減、屬性的變動、文本內容的修改等都會觸發MutationObserver事件。注意地,與事件不同,事件是同步觸發,DOM的變動會立即觸發事件,而MutationObserver事件是異步觸發,DOM不會立即觸發,需要等當前所有DOM操作完畢才會觸發。

MutationObserver有7個屬性:childList(true,監聽子節點的變動)、attributes(true,監聽屬性的變動)、characterData(true,監聽節點內容或節點文本的變動)、subtree(是否應用于該節點的所有后代節點)、attributeOldValue(觀察attributes變動時,是否需要記錄變動前的屬性值)、characterDataOldValue(觀察characterData變動時,是否需要記錄變動前的值)、attributeFilter(數組,表示需要觀察的特定屬性(比如[‘class’,‘src’])。

為什么需要創建一個文本節點?因為在這里操作DOM保證瀏覽器頁面是最新DOM渲染的,雖然看來好像是沒什么作用,但這是保證拿到的DOM是最新的。

Vue的this.$nextTick怎么使用

  • 支持setImmediatesetTimeout,setImmediate即時計時器立即執行工作,它是在事件輪詢之后執行,為了防止輪詢阻塞,每次只會調用一個。setTimeout按照一定時間后執行回調函數。

Vue的this.$nextTick怎么使用

好了好了,到了現在,我們都知道nextTick做了什么吧,但是我們有沒有想過這樣的一個問題:既然都是異步回調執行等待DOM更新后才去調用操作DOM的代碼,那么這個機制又是什么原理?這就是JS的執行機制有關了,涉及宏任務與微任務的知識,我們先來看看這樣的一道題:

console.log('同步代碼1');
setTimeout(function () {
    console.log("setTimeout");
}, 0);
new Promise((resolve) => {
    console.log('同步代碼2')
    resolve()
}).then(() => {
    console.log('promise.then')
})
console.log('同步代碼3');

我們可能會問上面的輸出是個啥,首先js是單線程,所以在js程序運行中只有一個執行棧,實現不了多線程,所以就需要任務均衡分配,通俗的講,按任務急優先處理原則,js中分為同步任務和異步任務,異步任務又分為宏任務和微任務,同步任務先入棧,程序會先把執行棧中的所有同步任務執行完,再去判斷是否有異步任務,而異步任務中微任務的優先級高于宏任務。如果當前執行棧為空,而微任務隊列不為空,就先執行微任務,等把所有微任務執行完,最后才會考慮宏任務。而上面代碼中Promise是屬于微任務,而setTimeout是宏任務,所以上面的輸出為:

// 同步代碼1
// 同步代碼2
// 同步代碼3
// promise.then 
// setTimeout

使用Vue2的nextTick

  • 傳入回調函數參數使用:

    s.$nextTick(()=>{
     // ...操作DOM的代碼
    })
  • 不傳入回調函數參數使用:

  • // 方式一
    this.$nextTick().then(()=>{
     // ...操作DOM的代碼
    })

    // 方式二
    await this.$nextTick();
    // 后寫操作DOM的代碼

Vue3版本的nextTick

Vue3版本就沒有Vue2版本的那么多環境支持,nextTick封裝成了一個Promise異步回調函數執行。

// Vue3.2.45
// core-main\core-main\packages\runtime-core\src
export function nextTick<T = void>(
  this: T,
  fn?: (this: T) => void
): Promise<void> {
  const p = currentFlushPromise || resolvedPromise
  return fn ? p.then(this ? fn.bind(this) : fn) : p
}

使用Vue3的nextTick

  • 傳入回調函數使用

  • import { nextTick } from 'vue' // 引入
    setup () {    
    nextTick(()=>{
      // ...操作DOM的代碼
    })
  • 不傳入回調函數的使用

  • import { nextTick } from 'vue' // 引入
    setup () {    
       // 方式一
       nextTick().then(()=>{
         // ...操作DOM的代碼
       })

       // 方式二
       await nextTick();
       // 后寫操作DOM的代碼
    }

以上就是關于“Vue的this.$nextTick怎么使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

丰顺县| 正宁县| 谢通门县| 万荣县| 新平| 那坡县| 隆回县| 吉林市| 景德镇市| 张家口市| 辽中县| 靖远县| 岳阳市| 吉木萨尔县| 宿松县| 宁蒗| 盐山县| 东平县| 云霄县| 犍为县| 麦盖提县| 巴彦淖尔市| 盘锦市| 建湖县| 勃利县| 马鞍山市| 清丰县| 静乐县| 奎屯市| 攀枝花市| 临夏县| 贺州市| 北京市| 郁南县| 阜平县| 红河县| 文成县| 峨眉山市| 盱眙县| 襄樊市| 石屏县|