vue中,我們所要實現(xiàn)的一個場景就是:
- 從列表頁 ------> 詳情頁蛉迹, 再從詳情頁 -----> 列表頁 ,要保存上次已經(jīng)加載的數(shù)據(jù)和自動還原上次的瀏覽位置
最近一個項目中遇見這個問題放妈,思來想去北救,總沒有特別好的方案,于是百度查找各種解決辦法芜抒,最后整理歸納如下解決思路:
1. 緩存組件珍策,vue2中提供了keep-alive。首先在我們的app.vue中定義keep-alive:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
這里是根據(jù)路由中的meta
源信息中的keepAlive
字段來判斷當前路由組件是否需要緩存挽绩。這里的meta
的keepAlive
是我們自定義的膛壹,當然你也可以叫別的名字。
2. 下面在router.js即我們的路由文件中唉堪,定義meta信息
// news 是列表頁
{
path: '/news ',
name: 'news ',
component: resolve => require(['@/view/news'], resolve),
meta: {
keepAlive: true // 通過此字段判斷是否需要緩存當前組件
}
},
這里采用路由懶加載,大家也可以使用 import 來導入肩民,無關(guān)緊要唠亚,接著看下面
緩存數(shù)據(jù)的實現(xiàn)
先簡單了解一下緩存相關(guān)的vue鉤子函數(shù)。
設(shè)置了keepAlive緩存的組件:
第一次進入:beforeRouterEnter > created > … > activated->…->deactivated 后續(xù)進入時:beforeRouterEnter > activated > deactivated
可以看出持痰,只有第一次進入該組件時灶搜,才會走created
鉤子,而需要緩存的組件中activated
是每次都會走的鉤子函數(shù)工窍。所以割卖,我們要在這個鉤子里面去判斷,當前組件是需要使用緩存的數(shù)據(jù)還是重新刷新獲取數(shù)據(jù).
頁面滾動位置的問題
- 我們知道患雏,在vue這種單頁應(yīng)用中鹏溯,如果你在a頁面滾動了一段距離后,此時前往b頁面后淹仑,b頁面也會停留在a頁面的滾動位置丙挽。這個問題的解決肺孵,我們可以利用router本身提供的功能來解決:
routes: [
{
path: '/detail',
name: 'Detail',
component: resolve => require(['@/view/detail'], resolve)
}
],
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
if (from.meta.keepAlive) {
from.meta.savedPosition = document.body.scrollTop;
}
return { x: 0, y: to.meta.savedPosition || 0 }
}
}
scrollBehavior
是路由提供的基礎(chǔ)功能,這段函數(shù)寫的是:
如果通過瀏覽器自帶的前進后退按鈕切換的路由颜阐,那么會自動使用瀏覽默認的回滾上次頁面的瀏覽位置平窘。
如果是通過vue路由進行的頁面切換。例如a前往b凳怨,首先判斷a是不是通過
keep-alive
緩存的組件瑰艘,如果是,則在a路由的meta中添加一個savedPosition
字段肤舞,并且值為a的滾動位置磅叛。最后return的是頁面需要回滾的位置。如此一來萨赁,如果打開一個頁面弊琴,該頁面的組件路由中meta.savedPosition
為undefined的話,則頁面滾動到(0,0)的位置杖爽,這樣解決了問題1敲董。那么如果打開一個頁面,它的路由的meta.savedPosition
有值的話慰安,則滾動到上次瀏覽的位置腋寨,因為meta.savedPosition
保存的就是上次瀏覽的位置。