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>