# Vue學習#18 keep alive 保留元件狀態 ###### tags: `Vue 直播班 - 2022 春季班` ## 為何需要保留元件狀態 如果我們為數個元件的 template 撰寫 input 輸入框,並用按鈕來切換不同元件的輸入框並用 v-model 綁定 data,你會發現當你修改完一個元件的輸入框之後,切到別的元件再切回來, 你剛更新的文字內容不會被保留下來了,這就是為什麼需要保留元件 ### [Vue 為何需要 keep alive](https://codepen.io/binlandz123/pen/YzedKBJ?editors=1010) ## 解決辦法 如果是使用 v-if 來做元件內容的切換時,可以將 v-if 改成 v-show 來避免切換元件時,元件被銷毀 但如果是使用 :is 來做動態切換元件哩? ## 使用 <keep-alive></keep-alive> `<keep-alive></keep-alive>` 這個特殊的元件標籤,<font color='red'>可暫存保留元件當下的狀態</font> keep-alive 是一個抽象元件,即是它不會被渲染成 DOM 節點掛載在畫面上 我們修改一下上面那個範例用 keep-alive 標籤包住元件,這樣修改了元件輸入框,就算切換資料還是會保留下來喔! ### [keep alive](https://codepen.io/binlandz123/pen/wvyRvwB) ## <keep-alive>的 include 、 exclude 、 max 屬性 要是切換的元件數量太多,每個都使用 keep alive 保留狀態,必定會造成效能的負擔 Vue 提供了 三個 keep-alive 屬性 1. include : 只有寫在 include 裡面的元件名稱才會被保留狀態 2. exclude : 寫在 exclude 的元件名稱不會被保留狀態 3. max : keep-alive 最多能保留多少元件 ```=vue <keep-alive include=" component-a , component-b " exclude=" component-c , component-d " max="3"></keep-alive> export default{ const componentA = { name: 'component-a' } // componentB ~ componentD 子元件都是要宣告 name } ``` ### 注意!如果使用 include 和 exclude props 來指定元件名稱時,該元件需要有 name 屬性才會生效。 **include 、 exclude 對應的條件為子元件的 name 屬性,而不是子元件的標籤名稱** ### [Vue keep alive props](https://codepen.io/binlandz123/pen/ZErVEXv?editors=1010) ## 特殊的生命週期 activated & deactivated 該元件在只會跑一次生命週期,之後只會跑 activated 和 deactivated 這兩個生命週期,代替 mounted 和 unmounted 如果沒有加上 <keep-alive> 標籤,在切換元件時重新觸發元件的各種生命週期,先從 created 開始到 mounted 掛載 順序: 建立新的元件 ( created ) -> 銷毀目前元件 ( unmounted ) -> 掛載新的元件 ( mounted ) 如果加上 <keep-alive> 標籤,當元件首次建立時,就會先進行 created -> mounted -> activated 等三個階段 順序: 建立新的元件 ( created ) -> 暫停目前元件 ( deactivated ) -> 掛載新的元件 ( mounted ) -> 啟用新的元件 ( activated ) 在前面執行過 created 而未被銷毀的元件,再次被啟用的時候,會直接執行 activated , 不會再從 created 開始建立 ```=vue activated() { ... } deactivated() { ... } ``` ## keep alive 使用時機 1. 減少呼叫 API 的次數。例如該元件每次重新渲染時都要呼叫 API 取資料,除了加重後端負擔,也會因為等候時間而影響使用者體驗。 2. 表單功能,當使用者按下「上一步」按鈕時,需要呈現在前一個元件裏他所填寫的資料 ## 參考 [不只懂 Vue 語法:請說明 keep-alive 以及 is 屬性的作用?](https://ithelp.ithome.com.tw/articles/10271305) 008天絕對看不完的 Vue.js