vue2.0中提供了一個keep-alive
的組建來緩存組件,避免屢次加載相應的組件,減小性能消耗。vue
keep-alive是Vue的內置組件,能在組件切換過程當中將狀態保留在內存中,防止重複渲染DOM,結合vue-router中使用。能夠緩存某個view的整個內容。正則表達式
語法:vue-router
<keep-alive>
<component>
<!-- 須要緩存的組件 -->
</component>
</keep-alive>
複製代碼
通常有這種需求的都是,第一次進入頁面時請求一次數據,後面經過路徑切換或者前進/後退進入改頁面時,頁面都使用的緩存數據,DOM不會刷新。緩存
<!-- a.vue -->
export default {
name: 'test',
data() {
return {
includedComponents: 'test'
}
}
}
複製代碼
結合exclude和include來進行條件緩存bash
<keep-alive include="test">
<!-- 將緩存name爲test的組件 -->
<component></component>
</keep-alive>
<keep-alive include="a,b">
<!-- 將緩存name爲a或者b的組件,結合動態組件使用 -->
<component :is="view"></component>
</keep-alive>
<!-- 使用正則表達式,需使用v-bind -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 動態判斷 -->
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
<keep-alive exclude="test">
<!-- 將不緩存name爲test的組件 -->
<component></component>
</keep-alive>
複製代碼
咱們可能會碰到這樣的需求,部分緩存:性能
主頁 - 列表頁 - 詳情頁
主頁 => 列表頁 【列表頁不須要緩存】
詳情頁 => 列表頁 【列表頁須要緩存】
複製代碼
網上有不少關於這個例子的解決方案,可是你們有沒有發現這種處理方法存在問題,代碼大概是這樣的。ui
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
複製代碼
list頁面路由this
{
path: '/list',
name: 'list',
component: list,
meta: {
keepAlive: true,
}
}
複製代碼
Home頁面設置spa
<!-- home.vue -->
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設置下一個路由的 meta
to.meta.keepAlive = false;
// Home 跳轉到 list 時,讓 list 不緩存,即刷新
next();
}
};
複製代碼
detail頁面prototype
<!-- detail.vue -->
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設置下一個路由的 meta
to.meta.keepAlive = true;
// detail 跳轉到 list 時,讓 list 緩存,即不刷新
next();
}
};
複製代碼
這種方案的bug:
也就是說只要從 Home => list,list的緩存設置失效,必須經歷一次detail => list 才能將keepAlive設置爲true,list才能達到緩存效果。
今天想說的重點 最近有一個需求是這樣的:
A_1 => A [A頁面須要緩存]
B_1 => B [B頁面須要緩存]
A => B [B不須要緩存]
B => A [A不須要緩存]
複製代碼
這種需求怎麼實現呢?最開始的想法是更改keepAlive的方式,最後發現行不通。最後的解決方案是
具體代碼: 路由設置
{
path: '/A',
name: 'A',
component: A,
meta: {
keepAlive: true,
}
},
{
path: '/B',
name: 'B',
component: B,
meta: {
keepAlive: true,
}
}
複製代碼
main.js中記錄上一個路由地址
router.beforeEach((to, from, next) => {
Vue.prototype.beforeRouter = from;
next();
})
複製代碼
A.vue頁面,
activated() {
const beforeRouterName = this.beforeRouter.name;
if (beforeRouterName && beforeRouterName !== 'A_1') {
// 手動刷新頁面
this.$refs.table.reload();
}
},
複製代碼
B.vue頁面
activated() {
const beforeRouterName = this.beforeRouter.name;
if (beforeRouterName && beforeRouterName !== 'B_1') {
// 手動刷新頁面
this.$refs.table.reload();
}
},
複製代碼
這樣就能夠實現只要不是B_1/A_1頁面進入到B/A時均可以將頁面刷新。可能不是最好的解決方案,
若是你有什麼更好的解決方法能夠留言; 查看更多相關信息可關注公衆號: