我們先看下面代碼示例效果:
(1)示例
<body>
<div id="app" >
<div id='div' v-if="showDiv">這是一段文本</div>
<button @click="getText">獲取div內容</button>
</div>
</body>
<script >
var app = new Vue({
el:'#app',
data : {
showDiv: false,
},
methods: {
getText(){
this.showDiv = true;
var text = document.getElementById('div').innerHTML;
console.log(text)
}
}
})
</script>
(2)頁面效果
我們看到在控制檯會拋出一個錯誤,意思是獲取不到div元素。這是涉及到一個概念:異步更新隊列。
說明:Vue在觀察到數據變化時並不是直接更新DOM,而是開啓一個隊列,並緩衝在同一事件循環中發生的所有數據改變。在緩衝時會去除重複數據,從而避免不必要的計算和DOM操作。然後在下一個事件循環tick中,Vue刷新隊列並執行實際(已去重的)工作。所以你用一個for循環來動態改變數據100次,其實它只會應用最後一個改變,如果沒有這種機制,DOM就要重繪100次,這是一個很大的開銷。
在執行this.showDiv = true;時,div仍然還沒有被創建出來,直到下一個Vue事件循環時,纔開始創建。$nextTick 就是用來直到什麼時候DOM更新完成。
方法修改爲:
getText(){
this.showDiv = true;
this.$nextTick(function () {
var text = document.getElementById('div').innerHTML;
console.log(text)
})
}
(3)小結
理論上我們不應該主動操作DOM,因爲Vue的核心思想就是數據驅動DOM,但是在很多業務中我們避免不了會使用第三方庫,比如popper.js、swiper等,這些基於原生JavaScript的庫都有創建和更新及銷燬的完整生命週期,與Vue配合使用時,就要利用好$nextTick.