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);
}
}
});
複製程式碼
效果:
看效果,點選按鈕後,DIV 顯示出來了。但卻無法獲取 DIV 中的資料:
因為 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'
});
複製程式碼