定义:<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
应用场景:1.tabs切换时保留切换前的操作;
2.前进刷新、后退缓存用户浏览数据和浏览位置;
相关内容:
只有用<keep-alive></keep-alive>包裹的组件才会有activated生命周期,使用<keep-alive>是组件被缓存了,没有被销毁,所以组件在切换的时候也就不会被重新创建,也就不会调用created等生命周期函数,所以此时要使用activated与deactivated来获取当前组件在每次进入页面的时候获取最新的数据。
第一次进入:beforeRouterEnter ->created->…->activated->…->deactivated
后续进入时:beforeRouterEnter ->activated->deactivated
- include: 字符串或正则表达式。只有匹配的组件会被缓存。
- exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
- activated()、deactivated() 钩子函数: 获取当前组件是否处于活动状态。
具体用法:关于前进刷新、后退返回的功能的实现
1.在我们的app.vue中或者是要显示视图组件的地方定义keep-alive;
// 方法一:在路由meta源信息中的keepAlive或者其他名字的字段来判断当前路由组件是否需要缓存
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
// 方法二:通过include或者exclude 来判断当前路由组件是否需要缓存
// 利用include实现,匹配到组件中定义的name,将进行缓存
<keep-alive include='home'>
<router-view />
</keep-alive>
2.在router/index.js也就是路由中,定义meta信息:
// list是我们的搜索结果页面
{
path: '/home',
name: 'home',
component: () => import ('@/pages/index'),
meta: {
title: '主列表页',
isUseCache: false, // 判断是否需要使用缓存数据的字段,false:重新刷新获取数据
keepAlive: true // 通过此字段判断是否需要缓存当前组件
}
},
3.在activated钩子函数里面判断,当前组件是需要使用缓存的数据还是重新刷新获取数据;
// 在index组件页面的activated钩子
activated() {
// isUseCache为false时才重新刷新获取数据
// 因为对index使用keep-alive来缓存组件,所以默认是会使用缓存数据的
if(!this.$route.meta.isUseCache){
this.list = []; // 清空原有数据
this.onLoad(); // 获取数据的函数
}
},
4. 只要index页面到detail页面的时候缓存index页面的数据,需要在index页面使用beforeRouteLeave的钩子判断,如果前往的是detail页面,则缓存index页面数据:
// index页面的beforeRouteLeave钩子函数
beforeRouteLeave (to, from, next) {
if (to.name == 'detail') {
from.meta.isUseCache = true;
}
next();
},
5. detail返回index页面,index页面已经被缓存数据了,如果需要前往list页面返回index页面想让index页面不缓存,则在路由设置index的isUseCache为true,并且在activated钩子函数中加上this.$route.meta.isUseCache=false; 来控制是否缓存;
// 在index组件页面的activated钩子
activated() {
// isUseCache为false时才重新刷新获取数据
// 因为对index使用keep-alive来缓存组件,所以默认是会使用缓存数据的
if(!this.$route.meta.isUseCache){
this.list = []; // 清空原有数据
this.onLoad(); // 获取数据的函数
}
// 控制是否要刷新
this.$route.meta.isUseCache = false;
},
6.再次以上,一个前进刷新、后退返回的功能基本完成了。但是在一些需要操作判断是否需要刷新的页面,借鉴一下vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践 - 掘金这篇文章的例子:
如果这个详情页是个订单详情,那么在订单详情页可能会有删除订单的操作。那么删除订单操作后会返回订单列表页,是需要列表页重新刷新的。那么我们需要此时在订单详情页进行是否要刷新的判断。简单改造一下详情页:
//detail页面的操作
data () {
return {
isDel: false // 是否进行了删除订单的操作
}
},
beforeRouteLeave (to, from, next) {
if (to.name == 'list') {
// 根据是否删除了订单的状态,进行判断list是否需要使用缓存数据
to.meta.isUseCache = !this.isDel;
}
next();
},
methods: {
deleteOrder () {
// 这里是一些删除订单的操作
// 将状态变为已删除订单
// 所以beforeRouteLeave钩子中就会将list组件路由的isUseCache设置为false
// 所以此时再返回list时,list是会重新刷新数据的
this.isDel = true;
this.$router.go(-1)
}
}