主要讲下啥是 keep-alive、具体到项目中怎么用的问题。 项目相关:panda-mall
首页
-->列表页
-->商详页
-->再返回
,这时候列表页应该是需要keep-alive
的。首页
-->列表页
-->商详页
-->返回到列表页(需要缓存)
-->返回到首页(需要缓存)
-->再次进入列表页(不需要缓存)
,这时候就是按需来控制页面的keep-alive
了。
按需缓存.gif
vue
中如何具体实现,我会说两种方式。(1)介绍
(2)实现
meta
对象里定义两个值: keepAlive
:这个路由是否需要缓存deepth
:深度,也就是页面之间的前进后退的层次关系 // 首页
{
path: '*',
name: 'Home',
// 路由懒加载:https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
// webpackPreload:https://www.jianshu.com/p/bbdcfeee7fbc
component: () => import(/* webpackPreload: true */ '@/views/home'),
meta: {
keepAlive: true,
deepth: 1
}
},
// 商品列表
{
path: '/product',
name: 'Product',
component: () => import('@/views/product'),
meta: {
keepAlive: true,
deepth: 2
}
},
// 商品详情
{
path: '/detail',
name: 'Detail',
component: () => import('@/views/detail'),
meta: {
keepAlive: true,
deepth: 3
}
},
<template>
<div id="app">
<keep-alive :include="include">
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
export default {
data() {
return {
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) {
const index = this.include.indexOf(from.name);
index !== -1 && this.include.splice(index, 1);
}
}
}
};
设置meta
、监听路由并判断
。这里有一定要注意的是:你的路由中定义的 name 和页面中定义的 name 一定要全等,并区分大小写!!! // router.js
{
path: '*',
name: 'Home', // name要大小写要一致
component: () => import(/ '@/views/home'),
meta: {
keepAlive: true,
deepth: 1
}
}
// home.vue
export default {
name: 'Home', // name要大小写要一致
}
(1)问题
name
一致来说,如果团队里面大家从一开始就都定义了一个规范那还好说,但是往往大家就name
保持一致这个就可能很难。(2)实现
meta.keeAlive
字段来进行判断的,但是不用定义deepth
深度了。 // 首页
{
path: '*',
name: 'Home',
component: () => import('@/views/home'),
meta: {
keepAlive: true
}
},
// 商品列表
{
path: '/product',
name: 'Product',
component: () => import('@/views/product'),
meta: {
keepAlive: true
}
},
// 商品详情
{
path: '/detail',
name: 'Detail',
component: () => import('@/views/detail'),
meta: {
keepAlive: true
}
},
<router-view>
添加一个key
,这个key
就像是我们使用v-for
循环所定义的一样,大家都知道,key
的作用就是一个标识对吧,作用于vue
在虚拟 dom 进行diff
算法,提高渲染效率。<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="key" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key" />
</div>
</template>
<script>
export default {
computed: {
key() {
return this.$route.fullPath;
}
}
};
</script>
keep-alive
了。 onClick() {
this.$router.push({
path: '/product',
query: {
t: +new Date()
}
})
}
http://localhost:8081/#/product?t=1585898137794