目錄
一、這個好用的內置組件是什么?
二、這個組件的主要功能
三、怎么使用?
四、使用注意事項
五、我的使用場景
一、這個好用的內置組件是什么?
今天在優化我的平臺應用時,發現一個好用的組件標簽--<keep-alive>
。
<keep-alive>
是 Vue.js 中的一個內置組件,它的主要作用是緩存動態組件實例,避免它們在切換時被銷毀和重新創建。這對于需要保留組件狀態(例如表單輸入、滾動位置等)的應用場景特別有用。通過使用 <keep-alive>
,可以顯著提升用戶體驗,因為不需要每次顯示組件時都重新加載或初始化它。
二、這個組件的主要功能
-
緩存組件:當包裹在
<keep-alive>
內的組件從激活狀態變為非激活狀態時,該組件實例不會被銷毀,而是會被緩存起來。當下次再次進入這個組件時,會直接從緩存中恢復,保持之前的狀態。 -
生命周期鉤子:當使用
<keep-alive>
包裹組件時,這些組件將擁有額外的生命周期鉤子:activated
: 當組件被激活時調用。這個deactivated
: 當組件停用時調用。
三、怎么使用?
使用上很簡單,只需要將組件放到這個<keep-alive></keep-alive>
標簽之內就可以了。
<template><div><button @click="currentComponent = 'ComponentA'">顯示組件 A</button><button @click="currentComponent = 'ComponentB'">顯示組件 B</button><!-- 使用 keep-alive 緩存組件 --><keep-alive><component :is="currentComponent"></component></keep-alive></div>
</template>
這里的<component is=""></component>
用法也是新發現的,is的屬性值填入組件名稱即可在這里添加這個組件。這里是通過一個變量來控制組件名稱,所以同一時間只會添加一個組件,相當于使用多個<組件1 v-if="current==''"></組件1>
。
因為使用了<keep-alive>
,所以在多個組件輪流切換顯示時,每個組件都不會被銷毀,而是被緩存。
還可以使用它的標簽內屬性進行一些個性控制。如:
- include:字符串或正則表達式。只有名稱匹配的組件會被緩存。
- exclude:字符串或正則表達式。任何名稱匹配的組件都不會被緩存。
- max:數字。最多可以緩存多少個組件實例。
<keep-alive include="ComponentA,ComponentB"><component :is="currentComponent"></component></keep-alive>
四、使用注意事項
使用<keep-alive>
時,需要注意,因為是緩存了組件實例,所以過度使用可能會導致客戶端內存占用增加。
<keep-alive>
無法與<組件1 v-show="current==''"></組件1>
的v-show結合使用,因為它們兩者的工作機制不同。
activated這個生命周期鉤子和使用了v-if進行顯示控制的組件里的mounted可點像,不會像使用v-show進行顯示控制的組件在主頁面加載時把所有組件里的mounted一次性全部都加載完,而是會在當前這個組件顯示(加載)時才執行。
也有點不像,不像的地方在于使用了v-if進行顯示控制的組件里的mounted只會在組件第一次顯示(也就是初次創建實例)時執行一次,而activated這個生命周期鉤子會在每次組件顯示(也就是激活)時,執行一次。
五、我的使用場景
我的場景是在主頁面下有三個標簽頁,我使用了三個組件作為三個標簽頁,使用v-if控制顯示/隱藏,然后標簽頁里各有一個scrollview需要計算尺寸。
本來使用v-if是沒問題的,每次切換標簽頁,都是銷毀/新建,計算放在mounted生命周期鉤子里都能正常計算出尺寸。但是標簽頁的數據也要每次清空重來,就換成了使用v-show來控制標簽頁的顯示/隱藏。
這時候,標簽頁的數據是不會清空重來了,但是后面兩個標簽頁的mounted在主頁面加載時,就和第一個標簽頁的mouted一起執行了,導致第一個標簽頁的scrollview尺寸計算沒問題,但是后面兩個的scrollview計算結果都是0。
因為使用v-show,本身標簽頁都是一次性加載到DOM中的,顯示設置了不顯示(display:none),所以會同時調用mounted,同時計算,而且計算結果只有顯示的這個scrollview是正確的尺寸,不顯示的scrollview尺寸就不正確了。
后來使用了<keep-alive>
,在類似v-if的控制情況(不會同時執行mounted)下,也不會銷毀組件實例,清空數據了。