Vue之動態組件詳解

Vue動態組件

一.背景

Vue 中提供有一個內置的組件叫做 component 。這個組件就是動態組件。它需要設置 is 屬性。is 屬性的值就是需要渲染的組件的名字

​ 動態組件在我們實際開發中是很有用的,比如我們要實現選項卡切換的操作,對應的選項卡內容是不同的組件,這時我們就可以考慮使用動態組件.

​ 我們知道,動態渲染組件的方式還很多種,比如使用v-if判斷,v-show實現組件樣式的顯示與隱藏,但是呢,一般我們要考慮到性能的問題

1.v-if動態加載

v-if操作,如果我們有很多組件需要動態的加載,那麼每一個組件都要去判斷,如果成百上千個,那你的代碼裏基本上就全是v-if了,其實這還不算什麼,最主要的是v-if操作,一直從創建到銷燬,會有dom開銷,頻繁切換的話,性能肯定很大的問題

額外擴展一句:使用v-if和v-once配合使用,可以達到v-show的性能要求

實際上使用動態組件時,也會有性能開銷,畢竟動態組件的原理也是這樣,切換過程中,也是組件的創建到銷燬操作,不過動態組件可以通過keep-alive來實現狀態保持,也就是緩存

2.v-show動態加載

v-show操作,雖然減少了頻繁切換的性能開銷,但是v-show實際上的原理只是做樣式 的顯示與隱藏,也就是說,在最開始加載的時候會全部加載,如果組件不大,可以這麼做,但是如果組件很龐大的話,初始加載,那肯定也是不友好的

那這裏,Vue中就給我們提供了一個內置組件:component也就是動態組件,可以解決這些問題

二.動態組件

動態組件就是幾個組件放在一個掛載點下,然後根據父組件的某個變量來決定顯示哪個

在掛載點使用 component 標籤,然後使用 is =“組件名”,它會自動去找匹配的組件名,根據對應的顯示;

1.動態組件實現

html:

		<section class="main">
            <component :is="current"></component>
        </section>
        <nav class='nav'>
            <a  @click="current='index'" href="javascript:">首頁</a>
            <a  @click="current='find'" href="javascript:">發現</a>
            <a  @click="current='my'" href="javascript:">我的</a>
        </nav>

js:

Vue.component('index', {
            template: `
                <div>我是首頁內容</div>
            `,
            beforeCreate() {
                console.log('beforeCreate index');
            },

            beforeDestroy() {
                console.log("beforeDestroy index");
            }
        });

        Vue.component('find', {
            template: `
                <div>我是發現內容</div>
            `,
            beforeCreate() {
                console.log('beforeCreate find');
            },

            beforeDestroy() {
                console.log("beforeDestroy find");
            }
        });

        Vue.component('my', {
            template: `
                <div>我是我的內容</div>
            `,
            beforeCreate() {
                console.log('beforeCreate my');
            },

            beforeDestroy() {
                console.log("beforeDestroy my");
            }
        });

        const vm = new Vue({
            el: '#app',
            data: {
                current: 'index'
            }
        });

上述代碼就實現了一個動態組件加載的代碼,其實理解起來很簡單,需要動態加載 的組件共同維護data中的current數據,然後通過需要切換的按鈕給綁定事件,去修改這個current爲當前哪一個組件即可.

但是我們會發現一些問題,當我們每次切換的時候,組件的生命週期鉤子函數也會相應觸發,也就是說動態組件切換時也會有創建銷燬的性能開銷,vue給我們提供了下面的解決辦法:keep-alive

2.keep-alive 狀態保持

Vue 中提供了一個 keep-alive 內置組件。可以實現組件的緩存。

當在這些動態組件之間切換的時候,你有時會想保持這些組件的狀態,以避免反覆重渲染導致的性能問題.在動態組件上使用keep-alive,來實現組件緩存,

 			<keep-alive>
                <component :is="current"></component>
            </keep-alive>

使用keep-alive 將component動態組件包裹起來

  			Vue.component('index', {
            template: `
                <div>
                    我是首頁內容
                    <p>{{name}}</p>
                    <button @click="name='zhangsan'">修改名字</button>
                </div>
            `,
            beforeCreate() {
                console.log('beforeCreate index');
            },

            beforeDestroy() {
                console.log("beforeDestroy index");
            },
            //當組件被keep-alive緩存時,會調用這個鉤子函數(激活時)
            activated() {
                console.log("activated  index");
                
            },
            //當組件被keep-alive緩存時,會調用這個鉤子函數(失活時)
            deactivated() {
                console.log("deactivated  index");
            },
            data() {
                return {
                    name: 'liuqiao'
                }
            }
        });

        Vue.component('find', {
            template: `
                <div>我是發現內容</div>
            `,
            beforeCreate() {
                console.log('beforeCreate find');
            },

            beforeDestroy() {
                console.log("beforeDestroy find");
            }
        });

        Vue.component('my', {
            template: `
                <div>我是我的內容</div>
            `,
            beforeCreate() {
                console.log('beforeCreate my');
            },

            beforeDestroy() {
                console.log("beforeDestroy my");
            }
        });

        const vm = new Vue({
            el: '#app',
            data: {
                current: 'index'
            }
        });

上述代碼中,我要在index組件中修改name屬性,然後切換到其他組件,再切換回來時,keep-aliver已經幫我保存了之前的操作狀態,這就是keep-alive的作用

2.1 被keep-alive緩存組件特點
  • 切換組件時,當前組件不會觸發銷燬的生命週期鉤子。也就是說不會銷燬了。

  • 切換回來時,也不會重新創建。(既然都沒有被銷燬,哪裏來的重新創建呢)

  • 會多出兩個生命週期的鉤子函數

    • activated 緩存激活 第一次會觸發,組件能被看到時

      一般跟created鉤子函數做一樣的事情:請求數據

    • deactivated 緩存失活 不能被看到

      一般跟beforeDestory做一樣的事情:清除定時器,移除全局事件監聽

  • 可以在 vue devtools 上看見組件的緩存情況

2.2 keep-alive的更多屬性設置
2.2.1 include 包含

使用方式

  • include=“組件1,組件2”
  • :include=[“組件1,組件2”] 數組形式,include前必須要有冒號
  • :include=’/^hello/’ 正則匹配,方式以hello開頭的
   <keep-alive include="index,find">
         <component :is="current"></component>
   </keep-alive>

只會緩存這兩個組件,其它的不被緩存

2.2.2 exclude排除

使用方式

  • exclude=“組件1,組件2” 注意 逗號前後不要有空格

  • :exclude=[“組件1,組件2”] 數組形式,exclude前必須要有冒號

  • :exclude=’/^hello/’ 正則匹配,方式以hello開頭的排除

    1. :exclude="[組件1, 組件2]"
    2. :exclude="/^hello/"

使用方式與include相反

   <keep-alive exclude="index,find">
         <component :is="current"></component>
   </keep-alive>

除了這兩個組件,其它的都被緩存

2.2.3 max 允許最大緩存的數量,默認無限制
   <keep-alive :max="5">
         <component :is="current"></component>
   </keep-alive>

先進先出原則 ,如果緩存隊列有十幾個,當超過最大緩存的數量後,會把第一次進來的擠掉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章