# 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. 表單功能,當使用者按下「上一步」按鈕時,需要呈現在前一個元件裏他所填寫的資料
## 參考
[什麼是 JSX? 為什麼要用 JSX?](https://ithelp.ithome.com.tw/articles/10271305)
008天絕對看不完的 Vue.js