說說 Vue.js 元件的高階特性-續篇

deniro發表於2018-12-29

說說 Vue.js 元件的高階特性-續篇

1 $nextTick

Vue.js 在檢測到資料發生變化時,會先開啟一個佇列,並在記憶體中迴圈遍歷所有的資料改變,去除中間資料改變過程,直接執行實際工作(比如 for 迴圈改變某個變數 10 次,那麼 Vue.js 只會執行最後一次更新操作)。這樣可以避免不必要的計算以及 DOM 操作,從而提高效能。這個佇列叫做非同步更新佇列。

我們來看這樣一個場景:一個預設隱藏的 DIV。點選按鈕後,顯示這個 DIV 並獲取其內容。

html:

<div id="app">
    <div id="title" v-if="isShow">科普教育同樣是一場接力跑</div>
    <button @click="get">獲取</button>
</div>
複製程式碼

js:

var app = new Vue({
	el: '#app',
	data: {
		isShow: false
	},
	methods: {
		get: function () {
			this.isShow = true;
			console.log(document.getElementById('title').innerHTML);
		}
	}
});
複製程式碼

效果:

說說 Vue.js 元件的高階特性-續篇

看效果,點選按鈕後,DIV 顯示出來了。但卻無法獲取 DIV 中的資料:

說說 Vue.js 元件的高階特性-續篇

因為 Vue.js 中的非同步更新佇列特性,所以在執行 this.isShow = true; 之後,實際上還未真正建立 DIV。這個 DIV 要到下一個 Vue 事件迴圈時,才會被建立。

使用 $nextTick,就可以在 DOM 真正更新之後,再執行相關操作啦O(∩_∩)O~

js 程式碼修改如下:

methods: {
	get: function () {
		this.isShow = true;
		 console.log(document.getElementById('title').innerHTML);
		this.$nextTick(function () {
			console.log(document.getElementById('title').innerHTML);
		});
	}
}
複製程式碼

Vue.js 的核心思想是資料驅動 DOM,所以一般情況下,我們不會去主動操作 DOM。但有時候,我們需要去呼叫一些基於原生的 JS 庫,這些庫有建立、更新以及銷燬等涉及生命週期的操作,這時我們就要用好 $nextTick 咯。

2 X-Templates

有時候,我們定義的模板內容很長、很複雜。這時我們可以在 <script> 標籤(型別為 text/x-template )中定義好,然後通過 id 進行引用。

html:

<div id="app2">
    <deniro-component></deniro-component>
    <script type="text/x-template" id="deniro-template">
        <div>無人機送快遞 漸行漸近</div>
    </script>
</div>
複製程式碼

js:

Vue.component('deniro-component', {
	template: '#deniro-template'
});

var app2 = new Vue({
	el: '#app2'
});
複製程式碼

渲染結果:

<div id="app2">
	<div>無人機送快遞 漸行漸近</div>
	<script type="text/x-template" id="deniro-template">
	無人機送快遞 漸行漸近
	</script>
</div>
複製程式碼

通過這種方式,不管模板定義的內容有多長或者多麼複雜,我們都可以應對咯。 還可以使用 webpack 來編譯單檔案的 *.vue,到時候就可以更優雅地編寫模板程式碼咯O(∩_∩)O~

3 手動掛載例項

在一些特殊場景下(比如開發一些複雜元件),需要動態建立 Vue 例項,這時就會用到 Vue 的構造器Vue.extend。使用 Vue 構造器初始化例項後,我們還需要通過 $mount 來手動掛載例項。 因為 $mount() 會返回例項本身,所以可以直接呼叫例項的其它方法。

html:

<div id="mount-div">

</div>
複製程式碼

js:

var DeniroComponent2 = Vue.extend({
	template: '<div>智慧門鎖新花樣:{{content}}</div>',
	data: function () {
		return {
			content: '人臉開門原來這麼簡單'
		}
	}
});
new DeniroComponent2().$mount('#mount-div');
複製程式碼

渲染結果:

<div>智慧門鎖新花樣:人臉開門原來這麼簡單</div>
複製程式碼

執行後,指定 div 中的內容會被直接替換為模板中定義的內容。

也可以這樣掛載:

new DeniroComponent2({
        el:'#mount-div'
});
複製程式碼

本文示例程式碼

相關文章