場景:
list頁面(要緩存),跳轉(zhuǎn)到details頁面,
需求:
1 從details頁面返回后 list頁面不刷新,并保持離開時(shí)的位置.
2 從其他任意頁面進(jìn)入list頁面,正常刷新
方案:
1 使用keep-alive包裹router-view
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 這里不會被keepalive -->
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
2 路由注冊,添加meta
{
path: '/list',
name: 'List',
component: () => import('@/pages/list.vue'),
meta: {
keepAlive: true
}
},
3 list.vue中使用beforeRouteLeave鉤子
beforeRouteLeave(to, from, next) {
if (to.name == "details") {
from.meta.keepAlive = true
} else {
from.meta.keepAlive = false
}
next()
},
4 在組件中記錄scroll滑動的距離
this.scrollTop = document.querySelector( ".scroll-box" ).scrollTop
keep-alive緩存組件重新激活時(shí)會觸發(fā)activated周期函數(shù),在此函數(shù)中做滾動,回到跳轉(zhuǎn)details.vue前的位置
activated() {
document.querySelector(".scroll-box").scrollTop = this.scrollTop
},
問題:
list頁面會由于數(shù)據(jù)的不同,重復(fù)緩存,details返回后的頁面不是它的真正的上級頁面
場景還原:
點(diǎn)擊/list?id=01 下的01-item 前往01-item-details,返回后為/list?id=01下的頁面,正常
再點(diǎn)擊/list?id=02 下的02-item 前往02-item-details,返回后仍為/list?id=01下的頁面,異常
原因:第二次返回list?id=02時(shí)返回的是keep-alive已緩存的組件(即第一次緩存的list組件)
解決問題:
手動銷毀已緩存的list組件,使其每次進(jìn)入list都重新緩存新的頁面;
1 使用keep-alive的exclude屬性(任何名稱匹配的組件都不會被緩存)
<keep-alive :exclude="exclude" >
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
data() {
return {
exclude: this.$exclude,
}
},
2 對list.vue中的beforeRouteLeave鉤子函數(shù)做修改
beforeRouteLeave(to, from, next) {
// 離開list頁面且進(jìn)入的不是details頁面
if (to.name != "details") {
// exclude添加匹配后,會自動銷毀已緩存的組件
this.$exclude.push(this.$options.name)
// 緩存組件銷毀后要把exclude中的匹配刪除,不然下次進(jìn)去頁面不會緩存當(dāng)前組件
setTimeout(() => {
for (let i = 0; i < this.$exclude.length; i++) {
if (this.$exclude[i] == this.$options.name) {
this.$exclude.splice(i, 1)
break
}
}
}, 0)
}
next()
},