一.應用場景
1.列表頁進入詳情頁,再從詳情頁返回列表頁;列表頁緩存不刷新。保持原來選中的查詢參數以及當前頁
2.某個新增頁面分為兩步,分為A頁面和B頁面;當第一步A頁面信息填好后,點擊下一步到第二步B頁面。再返回到第一步A頁面,A頁面信息不丟失。同理第二步填好信息返回到第一步,再回到第二頁,第二頁頁面信息不丟失。
二.解決步驟
1.App.vue
//isRouterAlive:通過先設置isRouterAlive為false再設置為true可實現組件的銷毀 <router-view v-slot="{ Component }" v-if="isRouterAlive"> <keep-alive> <component :is="Component" v-if="_this.$route.meta.keepAlive" :key="$route.name" /> </keep-alive> <component :is="Component" v-if="!_this.$route.meta.keepAlive" /> </router-view>
2.router.js
//設置meta const routes: Array<RouteRecordRaw> = [ { path: 'list', name: 'list', meta: { keepAlive: true, cacheList: ['detail'] }, component: () => import('@/views/list.vue') }, ] //路由攔截 router.beforeEach((to, from, next) => { //從cacheList中的任何一個頁面返回,當前頁面緩存 const cacheList: any = to.meta.cacheList if (cacheList) { if (cacheList.indexOf(from.name) > -1) { to.meta.keepAlive = true } else { //解決第一次不緩存問題 if (from.name) { to.meta.keepAlive = false } else { to.meta.keepAlive = true } } } next() }
3.list.vue
import { defineComponent, nextTick } from 'vue' import { onBeforeRouteLeave } from 'vue-router' export default defineComponent({ name: 'list', setup() { onBeforeRouteLeave((to, from, next) => { //當即將訪問的界面不是detail則銷毀組件,以免上一次緩存信息存在 const cacheList: any = ['detail'] if (cacheList.indexOf(to.name) === -1) { //銷毀緩存信息(vue3沒有_this.$destory()方法,所以通過v-if實現組件的銷毀) //vuex改變全局變量isRouterAlive的值 _this.$store.commit('menu/changeRouterAlive', false) nextTick(() => { _this.$store.commit('menu/changeRouterAlive', true) }) } next() }) } })
3.總結:
1.以上解決方法同樣適用vue2,只需要改動一些代碼用法即可;思路一樣
2.如果僅在beforEach中根據to.name判斷是否為detail,來設置 keepAlive為true,當從list進入到其他頁面,再從其他頁面回到list 然后list在進入detail最后返回list。這個時候會緩存上上次的緩存記錄
因此需要當從離開list到非detail頁面時,應銷毀組件
由於vue3.x不支持this.$detroy();因此通過改變isRouterAlive的值來實現組件的銷毀 先設置false,再設置為true。即實現組件的重新渲染。即上一個組件被銷毀
3.遺留問題
從別的頁面進入list。list第一次進入detail再返回未緩存;等后期找到解決辦法會更新