1、將需要緩存的頁面路由加上meta屬性:
meta:{keepAlive: true}
2、在app.vue里使用keepalive
將
<router-view></router-view>
改為
<keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"></router-view>
3、路由守衛
router.beforeEach((to, from, next) => {if ( ["operationRegistrationAdd"].includes(to.name) && to.query.type === "details" ) { from.meta.keepAlive = true; } else { from.meta.keepAlive = false; } next(); });
如果要用局部守衛的話:
列表頁:
beforeRouteLeave(to, from, next) { if ( ['operationRegistrationAdd'].includes(to.name) && to.query.type === 'details' ) { from.meta.keepAlive = true } else { from.meta.keepAlive = false } next() }
詳情頁:
beforeRouteLeave(to, from, next) { if ( ['operationRegistration'].includes(to.name) && from.query.type === 'details' ) { to.meta.keepAlive = true } else { to.meta.keepAlive = false } next() }
第三步用路由守衛去改變 keepAlive 的值會有bug,
優化一下:
data中聲明 key: 0,綁定到組件上,當 key 值發生更改時會觸發組件更新
列表頁使用 activated 生命周期進行判斷,如果是從 add 或 edit 回來那么重新請求接口,並且更改 key 值;路由前置守衛是當從列表頁的上一級頁面過來時刷新列表頁的組件
activated() { this.setTitle() const { type } = this.$route.params if (type === 'add' || type === 'edit') { this.getList()
this.key++ } }, beforeRouteEnter(to, from, next) { if (from.name === 'register') { next((vm) => { vm.key++ }) } next() }
詳情頁:在路由離開時在目標路由(list)的 params 對象下添加 type 值,前提是 list 路由在進入詳情時分別傳了對應的 add、edit、details
beforeRouteLeave(to, from, next) { to.params.type = from.query.type // 通過query傳來的type next() }
思路:使用 keep-alive 緩存的組件,不會反復的經歷 created 就會緩存下當前 list 頁面,當 add、edit、details 公用一個頁面時,需要傳遞一個 type 作為區別,在 list 頁面中通過 activated 生命周期對 type 進行判斷,如果是 add 或 edit 就重新請求接口,重新渲染列表;並且將滾動條的位置置頂,這個是通過改變 key 值,組件重新渲染。同時需要注意從哪個路由跳轉到當前列表頁的,要對那個路由進行判斷,每次進來的時候滾動條都是置頂的。