一個常見的的場景,html
主頁 --> 列表頁--> 詳情頁,詳情頁 --> 主頁 --> 列表頁vue
咱們但願,git
從 詳情頁 --> 列表頁 的時候頁面的狀態是緩存,不用從新請求數據,提高用戶體驗。程序員
從 列表頁 --> 主頁 的時候頁面,註銷掉列表頁,以在進入不一樣的列表頁的時候,獲取最新的數據。github
今天 讓咱們來實現這個需求。編程
在 代碼的世界裏 解決問題的 方法 歷來都不止一種。api
好比,從數組中找到一個的值索引:數組
能夠用最基礎的 for循環 遍歷,也能夠用indexOf這種工具函數,還能夠用findIndex forEach等更語義化的高階函數來遍歷。緩存
我參考了大量的文章,爬了官方的文檔,以後,找到了好幾種辦法,下面,讓咱們來一個個分析。ruby
let's begin , 咱們開始吧。🙌
解決掉提需求的人
😂 emm... ,相對於咱們的人生,可能代碼會更好掌控吧。
程序員活在本身想象的王國裏
我剛接觸電腦就發現電腦的妙處,電腦遠沒有人那麼複雜。若是你的程序寫得好,你就能夠和電腦處好關係,就能夠指揮電腦幹你 想幹的事。這個時候你是十足的主宰。 往往你坐在電腦面前,你就是在你的王國裏巡行,這樣的日子簡直就是天堂般的日子。 電腦裏的世界很大,編程人是活在本身想象的王國裏。你能夠想象到電腦裏細微到每個字節、每個比特的東西。
-- 雷軍(沒錯就是小米那個雷軍)
我很認同雷軍的說法,
人生能找到一個 熱愛 的東西很可貴,你 熱愛代碼 並 專一於它的話,
終有一天,
它會以各類各樣的方式回報給你:工資,認同感,成就感,和你一塊兒進步,內心共鳴的人。
你若怒放,蝴蝶自來。諸君共勉 (能騙一個相信,就少一個沙雕和我搶妹子🤣)
睡服♂提需求的人
😂emm..., 看着鏡子裏那張的臉,這輩子應該是沒辦法從臉上獲得任何的便利了...
keep-alive
keep-alive
是Vue
提供的一個抽象組件,主要用於保留組件狀態或避免從新渲染。
可是 keep-alive
會把其包裹的全部組件都緩存起來。
咱們把需求分解成2步來實現
思路以下圖:
router-view
出口<keep-alive>
<!-- 須要緩存的視圖組件 -->
<router-view v-if="$route.meta.keepAlive">
</router-view>
</keep-alive>
<!-- 不須要緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
複製代碼
Router
裏定義好須要緩存的視圖組件new Router({
routes: [
{
path: '/',
name: 'index',
component: () => import('./views/keep-alive/index.vue'),
meta: {
deepth: 0.5
}
},
{
path: '/list',
name: 'list',
component: () => import('./views/keep-alive/list.vue'),
meta: {
deepth: 1
keepAlive: true //須要被緩存
}
},
{
path: '/detail',
name: 'detail',
component: () => import('./views/keep-alive/detail.vue'),
meta: {
deepth: 2
}
}
]
})
複製代碼
咱們從官方文檔提供的api入手,
keep-alive
組件若是設置了 include
,就只有和 include
匹配的組件會被緩存,
因此思路就是,動態修改 include
數組來實現按需緩存。
<keep-alive :include="include">
<!-- 須要緩存的視圖組件 -->
<router-view v-if="$route.meta.keepAlive">
</router-view>
</keep-alive>
<!-- 不須要緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
複製代碼
讓咱們在app.vue裏監聽路由的變化,
export default {
name: "app",
data: () => ({
include: []
}),
watch: {
$route(to, from) {
//若是 要 to(進入) 的頁面是須要 keepAlive 緩存的,把 name push 進 include數組
if (to.meta.keepAlive) {
!this.include.includes(to.name) && this.include.push(to.name);
}
//若是 要 form(離開) 的頁面是 keepAlive緩存的,
//再根據 deepth 來判斷是前進仍是後退
//若是是後退
if (from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {
var index = this.include.indexOf(from.name);
index !== -1 && this.include.splice(index, 1);
}
}
}
};
複製代碼
須要注意的是
keep-alive
須要其包裹的組件有name屬性,
咱們上面的代碼中的 push
和 splice
的是 router
的 name
。
因此建議你們把 route
的 name
屬性設置和 route
對應component
的name
設成同樣的。
讓咱們驗證一下咱們的成果
在 vue-devtool 裏,灰色的組件,表明是緩存狀態的組件,注意觀察list
的變化。
keep-alive
,網上有方法,經過修改 route
配置裏的 meta
裏的 keepAlive
值來實現。直接修改 meta
的值,可能會出現上圖的狀況,keep-alive裏有一直有一個緩存的 list,正常的 rotuer-view
裏也有一個,
復現這個問題須要很長得篇幅,感興趣的朋友能夠本身去爬一下坑。
謝謝你們的點贊和回覆,我看好多人想要demo的源碼這裏分享一下。
由於我公司目前尚未,vue的項目給我施展拳腳。我當時寫demo的時候,想的也不是動畫方面的封裝和優化,
因此分享的demo裏的代碼裏,關於動畫,會有不少重複的代碼和醜陋的實現。還請多見諒
關於demo動畫的一些分析,能夠看個人前2篇文章