Vue 進階之路(十三)
阿新 • • 發佈:2019-05-07
之前的文章我們介紹了一下 vue 中的作用域插槽,本章我們來看一下動態元件與 v-once 指令。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>vue</title> 6 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 7 </head> 8 <body> 9 <div id="app"> 10 <child-one v-if="type === 'child-one'"></child-one> 11 <child-two v-if="type === 'child-two'"></child-two> 12 <p @click="handleClick">clickMe</p> 13 </div> 14 <script> 15 Vue.component("child-one", { 16 template: `<p>我是第一個子元件</p>` 17 }); 18 Vue.component("child-two", { 19 template: `<p>我是第二個子元件</p>` 20 }); 21 var app = new Vue({ 22 el: '#app', 23 data: { 24 type: "child-one" 25 }, 26 methods: { 27 handleClick() { 28 console.log("type 資料更改前", this.type); 29 this.type = this.type === "child-one" ? "child-two" : "child-one"; 30 console.log("type 資料更改後", this.type) 31 } 32 } 33 }) 34 </script> 35 </body> 36 </html>
上面的程式碼中,我們定義了兩個子元件 child-one 和 child-two,並且我們在父元件中定義了一個 handleClick() 方法,當點選時我們通過父元件中 type 的值來使兩個子元件進行顯隱,結果如下:
當點選 clickMe 時顯示結果符合我們的預期,其實上面的程式碼可以改成如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>vue</title> 6 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 7 </head> 8 <body> 9 <div id="app"> 10 <component :is="type"></component> 11 <p @click="handleClick">clickMe</p> 12 </div> 13 <script> 14 Vue.component("child-one", { 15 template: `<p>我是第一個子元件</p>` 16 }); 17 Vue.component("child-two", { 18 template: `<p>我是第二個子元件</p>` 19 }); 20 var app = new Vue({ 21 el: '#app', 22 data: { 23 type: "child-one" 24 }, 25 methods: { 26 handleClick() { 27 console.log("type 資料更改前", this.type); 28 this.type = this.type === "child-one" ? "child-two" : "child-one"; 29 console.log("type 資料更改後", this.type) 30 } 31 } 32 }) 33 </script> 34 </body> 35 </html>
我們將 <child-one> <child-two> 標籤刪除掉,改為 <component> 標籤內,並在標籤內寫上 :is="type",<component> 標籤是一個動態標籤的意思,我們也可以將它寫成 <p> 或者 <h1> 都行,:is="type" ,根據父元件 type 資料的值和 handleClick() 方法對 type 資料改變來確定 :is="type" 內 type 的值是 child-one 還是 child-two,這樣就能動態地改變時顯示 child-one 元件還是 child-two 元件,結果如下:
執行結果和上面是一樣的。
接下來我們來看一下 v-once 指令。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>vue</title> 6 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 7 </head> 8 <body> 9 <div id="app"> 10 <child-one v-if="type === 'child-one'"></child-one> 11 <child-two v-if="type === 'child-two'"></child-two> 12 <p @click="handleClick">clickMe</p> 13 </div> 14 <script> 15 Vue.component("child-one", { 16 template: `<p v-once>我是第一個子元件</p>` 17 }); 18 Vue.component("child-two", { 19 template: `<p v-once>我是第二個子元件</p>` 20 }); 21 var app = new Vue({ 22 el: '#app', 23 data: { 24 type: "child-one" 25 }, 26 methods: { 27 handleClick() { 28 console.log("type 資料更改前", this.type); 29 this.type = this.type === "child-one" ? "child-two" : "child-one"; 30 console.log("type 資料更改後", this.type) 31 } 32 } 33 }) 34 </script> 35 </body> 36 </html>
上面的程式碼中我們在每一個子元件的 template 模板中的 <p> 表內都加了一個 v-once 屬性,如果不加這個指令的話我們每次通過 handleClick() 方法來判斷 type 時,子元件就會進行一個銷燬,另一個重新掛載,就會消耗不必要的記憶體。加上 v-once 時,當第一次掛載時需要渲染一次,當銷燬時並不是徹底刪除掉,而是留在了記憶體中,當需要重新掛載時就不需要重新渲染,而是直接去記憶體中拿,這樣就能減少不必要的記憶體消耗。
&n