在Vue中,<keep-alive>
的include
屬性用于指定需要緩存的組件,其實現方式如下:
1. 基本用法
? 字符串形式:通過逗號分隔組件名稱,匹配到的組件會被緩存。
<keep-alive include="ComponentA,ComponentB"><component :is="currentComponent"></component>
</keep-alive>
此時僅緩存名稱為ComponentA
和ComponentB
的組件。
? 正則表達式:使用v-bind
動態綁定正則表達式,匹配組件名稱。
<keep-alive :include="/Component[A-Z]/"><component :is="currentComponent"></component>
</keep-alive>
此時匹配名稱以Component
開頭且后續為大寫字母的組件。
? 數組形式:通過數組動態指定緩存組件。
<keep-alive :include="['ComponentA', 'ComponentB']"><component :is="currentComponent"></component>
</keep-alive>
支持動態計算屬性返回數組,例如結合路由元信息。
2. 動態控制緩存
? 結合路由元信息:在路由配置中通過meta
字段標記需緩存的組件,再通過計算屬性動態生成include
值。
// 路由配置
const routes = [{ path: '/pageA', component: PageA, meta: { keepAlive: true } },{ path: '/pageB', component: PageB, meta: { keepAlive: false } }
];// 動態include
<keep-alive :include="cachedComponents"><router-view></router-view>
</keep-alive>computed: {cachedComponents() {return this.$route.matched.filter(route => route.meta.keepAlive).map(route => route.name);}
}
此方式通過路由元信息靈活控制緩存。
3. 注意事項
? 組件需設置name
屬性:include
通過組件名稱匹配,因此被緩存組件必須顯式定義name
屬性。
? 優先級:若同時存在include
和exclude
,exclude
的優先級更高。例如:
<keep-alive include="A,B" exclude="B"><component :is="currentComponent"></component>
</keep-alive>
此時僅緩存組件A
,因B
被排除。
4. 生命周期鉤子
被緩存的組件會觸發activated
(激活時)和deactivated
(停用時)鉤子,而非created
或mounted
,需在對應鉤子中處理狀態更新。
1. <keep-alive>
的生命周期流程
當組件被包裹在 <keep-alive>
內時,其生命周期會分為以下階段:
階段 | 觸發條件 | 回調鉤子 | 行為說明 |
---|---|---|---|
初次進入 | 組件首次被渲染 | created , mounted | 正常初始化,執行邏輯 |
切換至其他組件 | 組件被切換到非活動狀態 | deactivated | 停用回調,保存狀態或清理資源 |
再次被激活 | 組件重新進入活動狀態 | activated | 激活回調,恢復狀態或刷新數據 |
組件銷毀 | 緩存達到 max 限制或手動銷毀 | destroyed | 銷毀組件實例,釋放內存 |
2. 關鍵生命周期鉤子詳解
(1) activated
鉤子
? 觸發時機:組件從緩存中被重新激活時(例如用戶返回到該頁面)。
? 典型用途:
? 加載最新數據(例如從服務端獲取)。
? 恢復動態修改的 DOM 狀態(如滾動位置、定時器)。
? 更新組件內部狀態(如重置表單或重新計算數據)。
? 示例:
export default {activated() {console.log('組件被激活');this.fetchData(); // 刷新數據this.initTimer(); // 重啟定時器},
};
(2) deactivated
鉤子
? 觸發時機:組件被切換到緩存中(例如用戶跳轉到其他頁面)。
? 典型用途:
? 取消定時器或異步操作,避免內存泄漏。
? 保存當前狀態到本地存儲或 Vuex。
? 暫停動畫或視頻播放。
? 示例:
export default {deactivated() {console.log('組件被停用');clearInterval(this.timer); // 清除定時器this.saveScrollPosition(); // 保存滾動位置},
};
(3) destroyed
鉤子
? 觸發時機:當組件被徹底銷毀時(例如緩存滿后被移除,或調用 $destroy()
)。
? 典型用途:
? 釋放強引用資源(如 WebSocket 連接)。
? 清理全局事件監聽器。
? 注意:僅在組件被銷毀時觸發,緩存中的組件不會觸發此鉤子。
3. 生命周期對比(普通組件 vs <keep-alive>
組件)
鉤子 | 普通組件 | <keep-alive> 組件 |
---|---|---|
created | ? | ?(僅第一次初始化時觸發) |
mounted | ? | ?(僅第一次初始化時觸發) |
updated | ? | ? |
deactivated | ? | ?(停用時觸發) |
activated | ? | ?(激活時觸發) |
destroyed | ?(組件銷毀時觸發) | ?(緩存超限或手動銷毀時觸發) |
4. 實際應用場景
場景 1:頁面切換時保留滾動位置
export default {data() {return { scrollY: 0 };},activated() {// 恢復滾動位置window.scrollTo(0, this.scrollY);},deactivated() {// 保存滾動位置this.scrollY = window.scrollY;},
};
場景 2:列表頁滾動加載數據
export default {data() {return { page: 1, loading: false };},activated() {if (!this.loading) {this.fetchMoreData(); // 刷新數據}},
};
5. 注意事項
-
狀態管理:
? 緩存組件不會銷毀實例,因此需謹慎處理狀態(如避免重復請求數據)。
? 推薦結合 Vuex 或本地存儲管理全局狀態。 -
性能優化:
? 使用max
屬性限制緩存數量,避免內存占用過高。
? 在deactivated
中清理不必要的資源(如定時器、事件監聽)。 -
組件名匹配:
? 確保被緩存的組件顯式聲明了name
屬性(include/exclude
依賴組件名匹配)。
總結
<keep-alive>
的生命周期機制通過 activated
和 deactivated
鉤子,實現了組件狀態的暫停與恢復。