Vue.js - 路由 vue-router 的使用详解6(keep-alive使用2:结合router-view)
<keep-alive> 除了可以包裹普通组件外,它还可以配合 <router-view> 使用,将整个路由页面一起缓存下来。下面通过样例进行演示。
二、配合 router-view 使用
1,使用样例
(1)效果图
- 这是一个简单的 router-view 路由导航效果。当路由地址改变时,页面组件随之切换显示。
- 由于 router-view 是包裹在 <keep-alive> 中,可以看到切换后之前页面的内容和数据仍然保留,说明页面组件消失时并没有被销毁,而是缓存起来。

(2)样例代码
- 根实例(App.vue)
<template>
<div id="app">
<img src="./assets/logo.png">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
text-align: center;
}
</style>
- 首页面(index.vue)
<template>
<div>
<h1>首页</h1>
<input type="text" name="" value=""><br>
<router-link to="/hello">前往欢迎页</router-link>
</div>
</template>
<script>
export default {
name: 'index',
//keep-alive钩子函数:组件被激活时调用
activated() {
console.log('首页被激活');
},
//keep-alive钩子函数:组件消失,被缓存时调用
deactivated() {
console.log('首页被缓存');
}
}
</script>
- 欢迎页(hello.vue)
<template>
<div>
<h1>欢迎页</h1>
<input type="text" name="" value=""><br>
<router-link to="/">回到首页</router-link>
</div>
</template>
<script>
export default {
name: 'hello',
//keep-alive钩子函数:组件被激活时调用
activated() {
console.log('欢迎页被激活');
},
//keep-alive钩子函数:组件消失,被缓存时调用
deactivated() {
console.log('欢迎页被缓存');
}
}
</script>
2,钩子函数
(1)<keep-alive> 提供了如下两个生命周期钩子函数:
- activated():页面组件被激活时调用。即组件第一次渲染时会被调用,之后每次 keep-alive 激活时也会被调用。通常我们可以在这个方法中实现:每次进入页面的时候获取最新的数据。
- deactivated():页面组件被停用时调用。
(2)关于这两个钩子函数的调用要注意的是:
- 只有组件被 keep-alive 包裹时,这两个函数才会被调用。如果作为正常组件使用,是不会被调用的。
- 即使组件被 keep-alive 包裹,如果使用 exclude 排除之后,这两个钩子依然不会被调用。
(3)上面样例中,我们在页面组件内部的钩子函数中输出了一些信息。当我们打开首页,先跳转到欢迎页然后再跳回来,控制台输出如下:

三、只缓存 router-view 里面的部分组件页面
如果只想 router-view 里面某个、或某些页面组件被缓存,通常有如下两种办法:
- 使用 include/exclude 来实现
- 配合 router.meta 属性来实现
1,使用 include/exclude 来实现
(1)这两个属性的作用前文也介绍过:
- include:只有匹配的组件会被缓存(支持字符串或正则表达)
- exclude:任何匹配的组件都不会被缓存(支持字符串或正则表达)
(2)使用样例
- 只缓存 name 为 index 的组件:
<keep-alive include="index"> <router-view/> </keep-alive>
- 不缓存 name 为 index 的组件:
<keep-alive exclude="index"> <router-view/> </keep-alive>
- 只缓存 name 为 index 或 hello 的组件:
<keep-alive include="index,hello"> <router-view/> </keep-alive>
- 只缓存以 in 开头的组件(使用正则表达式,需使用 v-bind):
<keep-alive :include="/^in.*/"> <router-view/> </keep-alive>
- 也可以动态绑定需要缓存的组件:
<keep-alive :include="includedComponents"> <router-view/> </keep-alive>
2,配合 router.meta 属性来实现
(1)首先我们在路由元信息 meta 中添加个 keepAlive 属性,用来表示那些页面组件需要缓存,那些不需要。
import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index' //引入首页组件
import hello from '@/components/hello' //引入欢迎页组件
//Vue全局使用Router
Vue.use(Router)
const router = new Router({
routes: [ //配置路由,使用数组形式
{
path: '/', //链接路径
name: 'index', //路由名称
component: index, //映射的组件
meta: {
keepAlive: true // 需要缓存
}
},
{
path: '/hello',
name: 'hello',
component: hello,
meta: {
keepAlive: false // 不需要缓存
}
}
]
})
export default router
(2)接着我们对根实例(App.vue)代码做如下修改。通过判断元数据的 keepAlive 属性值,来决定路由视图是放在 <keep-alive> 里面(需要缓存),还是外面(不需要缓存)
<template>
<div id="app">
<img src="./assets/logo.png">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
四、页面动态决定是否需要缓存
有时对于同一个页面组件,并不是一直都需要缓存,或者一直都不缓存。而是根据情况动态地改变。实现这种需求同样是通过配合 router.meta 属性来实现,我们根据情况动态地改变里面的 keepAlive 属性值即可。
1,效果图
(1)当我们从首页跳转到欢迎页再跳回来,发现首页内容仍然保留,说明首页是缓存的。

(2)当我们从首页跳转到关于页再跳回来,发现首页内容已经清空,说明首页这时又不缓存了。

2,样例代码
(1)在欢迎页(hello.vue)路由离开这个钩子函数中设置首页缓存:
<template>
<div>
<h1>欢迎页</h1>
<input type="text" name="" value=""><br>
<router-link to="/">回到首页</router-link>
</div>
</template>
<script>
export default {
name: 'hello',
//keep-alive钩子函数:组件被激活时调用
activated() {
console.log('首页被激活');
},
//keep-alive钩子函数:组件消失,被缓存时调用
deactivated() {
console.log('首页被缓存');
},
beforeRouteLeave(to, from, next) {
//设置下一个路由的meta(即首页)
to.meta.keepAlive = true; //让首页缓存,即不刷新
next();
}
}
</script>
(3)在关于页(about.vue)路由离开这个钩子函数中设置首页不缓存:
<template>
<div>
<h1>关于页</h1>
<input type="text" name="" value=""><br>
<router-link to="/">回到首页</router-link>
</div>
</template>
<script>
export default {
name: 'hello',
//keep-alive钩子函数:组件被激活时调用
activated() {
console.log('首页被激活');
},
//keep-alive钩子函数:组件消失,被缓存时调用
deactivated() {
console.log('首页被缓存');
},
beforeRouteLeave(to, from, next) {
//设置下一个路由的meta(即首页)
to.meta.keepAlive = false; //让首页不缓存,即刷新
next();
}
}
</script>
