溫馨提示×

溫馨提示×

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

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

Vue?nextTick如何獲取更新后的DOM的實現(xiàn)

發(fā)布時間:2022-01-25 10:44:17 來源:億速云 閱讀:318 作者:kk 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細講解有關(guān)Vue nextTick如何獲取更新后的DOM的實現(xiàn),文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

前兩天在開發(fā)時遇到一個需求:打開對話框的時候自動聚焦其中的輸入框。由于原生的 autofocus 屬性不起作用,需要使用組件庫提供的 focus 方法手動手動獲取焦點。于是有如下代碼:

<el-button @click="openDialog">點擊打開 Dialog</el-button>

<el-dialog :visible.sync="dialogVisible">
  <el-input v-model="input" ref="input"></el-input>
</el-dialog>
methods: {
  openDialog() {
    this.dialogVisible = true;
    const input = this.$refs.input;
    input.focus();
  },
},

結(jié)果報錯了,原因是沒有獲取到 input 組件;通過 log,也驗證了 this.$refs.input 的值確實是 undefined。但是經(jīng)過測試,如果對話框默認狀態(tài)是打開的,就不會報錯;明明組件就在那,為什么獲取不到呢?

生命周期 update

經(jīng)過分析,這種現(xiàn)象是由于 Vue 實例的更新機制造成的。從下方的生命周期圖(局部)中可以看出,組件裝載好之后,遇到數(shù)據(jù)變化時將重新渲染虛擬 DOM(可以理解為 HTML 中的組件節(jié)點)。在本例中,隱藏的 Dialog 組件(以及其中的 input 組件)本來并沒有渲染在 DOM 中,是在觀察到 dialogVisible 屬性變?yōu)?true 后再進行更新渲染的。

Vue?nextTick如何獲取更新后的DOM的實現(xiàn)

而網(wǎng)頁渲染通常是一個異步任務,因此在 visible 屬性剛剛更改時(一個函數(shù)中是同步過程),DOM 渲染還沒有進行,因此自然獲取不到此時還不存在的 input 組件了。

關(guān)于異步、JS任務隊列、宏任務與微任務等概念的更多介紹,可參考博文JS多線程:任務隊列

為了更直觀地展示這個過程,可以在更新前后的鉤子函數(shù)中試圖獲取組件并進行打印:

beforeUpdate() {
  console.log("beforeUpdate");
  const input = this.$refs.input;
  console.log(input);
},
updated() {
  console.log("updated");
  const input = this.$refs.input;
  console.log(input);
},
methods: {
  openDialog() {
    this.dialogVisible = true;
    console.log("click open");
  },
},

結(jié)果如下,可以驗證之前的分析和猜想:

click open
beforeUpdate
undefined
updated
VueComponent {...}

Vue.nextTick

為了解決這個問題,Vue 提供了全局 api Vue.nextTick(),它的作用是提供下次 DOM 更新之后的回調(diào)。也就是說,在更新數(shù)據(jù)后調(diào)用 api,就能夠獲取到重新渲染后的 DOM 并進行相關(guān)操作。

nextTick 方法可以廣泛適用于各種需要在數(shù)據(jù)更新后對相關(guān) DOM 進行操作的情景,例如 v-if 、watch 等。

在上文的例子中再加入 nextTick:

openDialog() {
  this.dialogVisible = true;
  console.log("click open");
  this.$nextTick(function () {
    console.log("next tick");
    const input = this.$refs.input;
    console.log(input);
    input.focus();
  });
},

可以看到,回調(diào)確實是在 DOM 更新之后,也就是 updated 執(zhí)行之后才執(zhí)行的。獲取組件與手動獲得焦點的操作也能夠正確執(zhí)行了。

click open
beforeUpdate
undefined
updated
VueComponent {...}
next tick
VueComponent {...}

Promise

如果沒有提供回調(diào)參數(shù),并且瀏覽器支持 Promise,調(diào)用 nextTick 將返回一個 Promise。也就是說下面幾種寫法是等價的(環(huán)境支持的情況下):

Vue.nextTick(function () {...})
Vue.nextTick(() => {...})

Vue.nextTick().then(function () {...})
Vue.nextTick().then(() => {...})

Vue的優(yōu)點

Vue具體輕量級框架、簡單易學、雙向數(shù)據(jù)綁定、組件化、數(shù)據(jù)和結(jié)構(gòu)的分離、虛擬DOM、運行速度快等優(yōu)勢,Vue中頁面使用的是局部刷新,不用每次跳轉(zhuǎn)頁面都要請求所有數(shù)據(jù)和dom,可以大大提升訪問速度和用戶體驗。

關(guān)于Vue nextTick如何獲取更新后的DOM的實現(xiàn)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(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