1. 程式人生 > >vue2.X基礎知識七之$nextTick

vue2.X基礎知識七之$nextTick

<div id="app">
    <div id="div" v-if="showDiv">這是一段文字</div>
    <button @click="getText">獲取div內容</button>
</div>
<script>
        var app = new Vue({

            //選擇元素
            el: "#app",
            data: {
            	showDiv: false
            },
            
            //通過事件觸發
            methods: {
            	getText: function() {
            		this.showText = true;
			var text = document.getElementById('div').innerHTML;            		
            		console.log(text);
            	}
            }
        });
</script>

上面程式碼執行後,會丟擲一個錯誤: cannot read property 'innerHTML' of null;這裡涉及到一個重要的概念: 非同步更新佇列

Vue在觀察到資料變化時並不是直接更新DOM,而是開啟一個佇列,並緩衝在同一事件迴圈中發生的所有資料改變。在緩衝時會去除重複資料,從而避免不必要的計算和DOM操作。然後,在下一個事件迴圈tick中,Vue重新整理佇列並執行實際工作。

事實上,在執行this.showDiv = true;時,div仍然還是沒有被創建出來,直到下一個Vue事件迴圈時,才開始建立。$nextTick就是用來知道什麼時候DOM更新完成的,所以上面的示例程式碼需要修改為:

<div id="app">
        <div id="div" v-if="showDiv">這是一段文字</div>
        <button @click="getText">獲取div內容</button>
    </div>
    <script>
        var app = new Vue({

            //選擇元素
            el: "#app",
            data: {
            	showDiv: false
            },
            
            //通過事件觸發
            methods: {
            	getText: function() {
            		this.showDiv = true;
			// 等待dom更新完成後執行回撥		
            		this.$nextTick(function() {
            			var text = document.getElementById('div').innerHTML;
            			console.log(text);
            		});
            	}
            }
        });   
    </script>
理論上,我們應該不用主動去操作DOM,因為Vue的核心思想就是資料驅動DOM,但在很多業務裡,我們避免不了會使用一些第三方庫,比如swiper等,這些機遇原生js的庫都有建立和更新及銷燬的完整宣告週期,與Vue配合使用時,就要利用好$nextTick。