【vue進階之旅】如何使用keep-alive做組件緩存?

語言: CN / TW / HK

前言

大家好,我是東東吖,一名前端工程師。今天我要給大家分享的是如何使用keep-alive做組件緩存?

為什麼要做組件緩存?什麼場景下會用到組件緩存?或許很多小夥伴根本不知道keep-alive這個組件,也或許知道keep-alive可以做組件緩存,但是卻從來沒有實踐過,懵懵懂懂,剛好我曾經有過使用keep-alive做組件緩存相關的項目經驗,現在我就給大家分享一下keep-alive這個組件到底是怎麼回事?在項目中應該怎麼用?應該注意些什麼?

keep-alive的使用場景?

現在給大家講一講keep-alive的使用場景,比如你在購物網站,不斷地滾動屏幕,當滾動到了很久很久,你突然發現一件你很喜歡的商品,你點擊進入詳情,當你查看了該商品的詳情,返回出來要保持之前的位置繼續往下瀏覽商品,你會怎麼做?再比如你在一個頁面有多個tab,默認是會選中第一個tab,當你在第二個tab切換到其他頁面的時候(比如對應tab的詳情),再次返回到當前的頁面,要保持你去之前的tab和對應的狀態,你會怎麼做?

這裏如果沒有使用組件緩存的話,當你點擊商品詳情頁面,當前商品列表的頁面就會銷燬,當你從商品詳情返回到商品列表的時候,這個頁面已經重新進行了構建,是不會保存在你之前剛剛瀏覽的位置的,又會返回到最頂上的位置,這個時候你讓用户再重複把剛剛的內容再刷一遍嗎?而用户的需求是繼續之前的位置,可以接着往下滑。切換tab的場景也是這樣的道理,不會保存你離開之前的狀態,下面我會深入講解。

vue的八大生命週期

我目前寫了一個tab案例,幫助大家理解keep-alive,對應的邏輯和代碼如下: 一共有tab1和tab2兩個頁面,點擊按鈕會顯示對應tab的內容,點擊color按鈕,會變更內容的顏色,同時會在控制枱打印所有生命週期。

```

```

當我們進入頁面,當前頁面的組件會被創建,並會顯示tab的內容,觸發從構建待到掛載相關的生命週期。 ``` beforeCreate........ created.....組件創建了 beforeMount........ mounted........

```

image.png

當我們點擊tab2按鈕會切換到tab2的內容,頁面發生改變,會觸發組件更新相關的生命週期 beforeUpdate........ updated........

image.png

當我們點擊color按鈕,會給tab2的內容變跟一個顏色,頁面發生改變,還是會觸發組件更新相關的生命週期 beforeUpdate........ updated........

image.png

當我們點擊其他頁面,當前頁面進會進行銷燬,會觸發組件銷燬相關的的生命週期: beforeDestroy.... index.vue?6ced:62 destroyed.....組件銷燬了

image.png

如何利用keep-alive做組件緩存?

現在問題來了,當我們再次進入剛才的頁面,頁面優化重新進行構建,並且會默認顯示tab1的內容,文字的顏色也是默認黑色。

image.png

如果我們現在重新切換到剛剛的頁面,想要默認顯示tab2的內容,並且顏色是經過變更的,也就是想要返回之後,保存我們切走前的狀態,該怎麼辦呢?

那就需要用到我們的keep-alive組件緩存,我們keep-alive組件是vue的官方組件無需註冊,直接使用,當我們直接把keep-alive的組件包裹 ,就能到達我們的效果,我們把他加上再試一下。

image.png

我們發現keep-alive維持了我們離開當前頁面的效果,同時控制枱的生命週期也有了一些變化,那是怎麼回事呢?

使用keep-alive之後,vue生命週期有何變化?

當我們使用keep-alive之後,我們首次進入該頁面

image.png 我們會發現會多一個生命週期activated,這個生命週期代表組件被激活了。 beforeCreate........ created.....組件創建了 beforeMount........ mounted........ activated........組件激活了

image.png

當我們離開當前頁面,會觸發另外一個生命週期deactivated,這個生命週期代表組件失活了,並且你會發現,當我們離開當前頁面,並不會觸發組件銷燬的生命週期,也就説明當前組件並沒有被銷燬,而是被緩存起來了,這也是我們為啥能實現我們想要效果的原因。

image.png

當我們反覆切換其他頁面和當前頁面,從第二次進入當前頁面會觸發activated,離開當前頁面會觸發deactivated,並不會再去觸發beforeCreate、created、beforeMount、mounted這四個生命週期,所以我們做項目使用keep-alive做組件緩存的時候,調用的接口應該是在組件被激活時的生命週期activated去掉,而不是在created生命週期去掉,因為created只會執行一次。

keep-alive 的屬性配置

keep-alive會緩存被包裹的組件,當我們包裹在 就説明整個項目的路由都被緩存了,如果我們想要只緩存部分頁面,該怎麼辦呢?

``` 在keep-alive上有兩個屬性:

include 值為字符串或者正則表達式匹配的組件name會被緩存。 exclude 值為字符串或正則表達式匹配的組件name不會被緩存,其它組件全部緩存。

``` 首先利用include實現,匹配到組件中定義的name,將進行緩存 image.png

image.png

當我們切換路由的時候就會發現,只有name為KeepAlive的這個組件被緩存了,其他路由被未被緩存,你可以在企業路由同樣打印對應的生命週期。

image.png

其次我們再來利用exclude實現,匹配的組件name不會被緩存,其它組件全部緩存。 我們把include直接換成exclude,再次切換組件路由,我們會發現生命週期模塊在執行一次生命週期created等生命週期之後,就沒有執行了(有執行組件緩存的兩個生命週期,只是我沒打印),説明被組件換成了,而組件緩存模塊一直在執行created等生命週期,而沒執行組件緩存的兩個生命週期了。

image.png

當然就是keep-alive組件緩存的使用方式,當然keep-alive的使用方式並不止這一種,歡迎大家留言討論。

結束

對於本文章,你有任何疑問,可在評論區留言交流。另外,我自己建了一個前端技術交流羣,羣成員工作年限0-10年都有,如果想進前端技術交流羣,可以加我微信fangdongdong_25,請備註掘金哦。