背景:在vue3 h5開發中,在列表的詳情頁里有一個tabs組件,點擊某一個tab下面的內容進入子頁面,從子頁面返回詳情頁的時候由于頁面重新進行了初始化,沒有保留之前選中的tab,產品提出優化需求。于是想起了keep-alive這個內置組件。
App.vue
用store把include
的內容做成動態的,包含某個頁面的時候會把該頁面加入緩存,移除某個頁面的時候會把該頁面移出緩存。
<router-view v-slot="{ Component }">
<keep-alive :include="orderStore.keepAlivePages">
<component :is="Component" />
</keep-alive>
</router-view>
import { useOrderStore } from "@/store"
const orderStore = useOrderStore();
store/order.ts
store里面有setKeepAlivePages(添加緩存頁面),和removeKeepAlivePage(移除緩存頁面)的方法。
state: () => ({
keepAlivePages: []
}),
actions: {
// 添加需要keep-alive的頁面
setKeepAlivePages(data: string) {
if (this.keepAlivePages.includes(data)) return;
this.keepAlivePages.push(data);
},
// 移除需要去除keep-alive的頁面
removeKeepAlivePage(data: string) {
if (!this.keepAlivePages.includes(data)) return;
const index = this.keepAlivePages.indexOf(data);
this.keepAlivePages.splice(index, 1);
}
}
acceptanceDetail.vue——詳情頁
進入詳情頁的時候把頁面加入緩存。
它會根據組件的
name
選項進行匹配,所以組件如果想要條件性地被KeepAlive
緩存,就必須顯式聲明一個name
選項。
import { useOrderStore } from "@/store"
const orderStore = useOrderStore();
// composition api可以通過defineOptions來設置name選項
defineOptions({
name: "AcceptanceDetail"
});
// 剛進入頁面的時候會執行onMounted
onMounted(() => {
orderStore.setKeepAlivePages("AcceptanceDetail");
initData();
});
// 頁面被添加到keep-alive里面之后會執行onActivated
// 在這里寫組件被激活后的操作
onActivated(() => {
initData();
});
acceptanceList.vue——列表頁
回到列表頁的時候清除緩存。做這一步是因為發現在詳情頁里面雖然可以通過onActivated生命周期鉤子重新請求數據,但是tabs組件還是緩存了,即使重新初始化也不行。導致從列表頁點擊一個新的訂單進來詳情頁,新訂單的詳情頁的tab選中的還是上一個訂單的。所以想到清除緩存。
import { useOrderStore } from "@/store"
const orderStore = useOrderStore();
onMounted(() => {
orderStore.removeKeepAlivePage("AcceptanceDetail");
});