我們能夠知道,一般情況下,組件進行切換的時候,默認會進行銷毀,這里我們定義 Home 和 About 兩個組件,每個組件都放置一個輸入框,並使用鈎子函數 created 和 destoryed 來顯示每個組件的創建和銷毀:
一開始進入頁面時組件 Home 創建:
進入組件 About 時,About 創建,Home銷毀:
但是如果有需求,某個組件切換后不進行銷毀,即切換到 About 時,Home 不進行銷毀,而是保存之前的狀態,那么就可以利用keep-alive來實現。
keep-alive
可以在組件切換時,保存其包裹的組件的狀態,使其不被銷毀,避免重新渲染。其擁有兩個獨立的生命周期鈎子函數 actived 和 deactived,使用keep-alive
包裹的組件在切換時不會被銷毀,而是緩存到內存中並執行 deactived 鈎子函數,命中緩存渲染后會執行 actived 鈎子函數。
使用 keep-alive 包裹組件
App 組件
接着我們在組件Home的輸入框中輸入666,再切換到組件About,並在About的輸入框中輸入888,我們可以發現切換到組件About時,組件Home沒有被銷毀。那這是不是說明我們緩存成功了呢?
接着,我們再切回到組件Home,發現輸入框中的內容還存在,這說明我們緩存成功了,歐耶!
但是別急着高興,因為我們發現組件About也被緩存了,而我們上面的需求是只緩存Home,所有的組件都被緩存了,嚴重影響性能。這時就要用到我們 keep-alive 的兩個屬性了:
props
- include - 字符串或正則表達,只有匹配的組件會被緩存
- exclude - 字符串或正則表達式,任何匹配的組件都不會被緩存
我們用 include 實現只緩存組件Home:
然后我們重復上面最后一步切回組件Home ,發現About已被銷毀,
再切回組件About時,輸入框中的888已經不存在了,組件About也被重新創建,而組件Home也沒有被銷毀。
好了,到這里我們已經完成了我們的需求,對於另一個屬性 exclude 這里就不演示了,它和 include 的用法一樣,只是它選中的組件與 include 相反不被緩存。
另外,除了使用組件的name值來控制緩存組件外,我們還可以使用路由的 meta 屬性來控制:
keep-alive 代碼可以結合v-if進行包裹,如果meta中的keepAlive為true進行緩存,否側不進行緩存,這樣可以更靈活一些
這樣組件的緩存是實現了,但是還是會有一些問題,就是因為組件是被緩存,並沒有被銷毀,所以組件在切換的時候也就不會被重新創建,自然也就不會調用created、destroyed等生命周期函數,即我們無法監聽是否離開或者進入被緩存組件,所以此時要使用上面提到的 keep-alive 的生命周期函數 activated 與 deactivated 來獲取當前組件是否處於活動狀態。
生命周期函數
- activated
在 keep-alive 組件激活時調用,該鈎子在服務器渲染期間不被調用
- deactivated
在 keep-alive 組件停用時調用,該鈎子在服務器渲染期間不被調用
注意: 只有組件被 keep-alive 包裹時,這兩個生命周期函數才會被調用,如果作為正常組件使用,是不會被調用的,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,這兩個鈎子函數依然不會被調用!另外,在服務端渲染時,此鈎子函數也不會被調用。
在組件 Home 里面加入兩個生命周期函數:
進入組件Home 和離開組件Home:
最后補充一下使用了keep-alive后的生命周期順序:
- 不使用keep-alive的情況:beforeRouteEnter --> created --> mounted --> destroyed
- 使用keep-alive的情況:beforeRouteEnter --> created --> mounted --> activated --> deactivated
- 使用keep-alive,並且再次進入了緩存頁面的情況:beforeRouteEnter -->activated --> deactivated
參考資料:https://blog.csdn.net/weixin_41819098/article/details/89379734?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.no_search_link