Vue Keep-alive使用
由于组件不支持v-if指令,所以我们在App.vue中采用两个的写法,通过当前路由的keepAlive字段来判断是否对页面进行缓存。假如有这样一个场景:我们当前所处在A组件,当我们跳转到B组件时(A组件被销毁,B组件被创建)当组件缓存之后,其他的生命周期不会走,但这个每次进去组件都触发,相当于。当组件缓存之后,其他的生命周期不会走,但这个每次离开组件都触发,相当于。但是,当我们又从B组件回到A组件
keep-alive是vue原生自带的,用来缓存组件的
解析: keep-alive是 Vue提供的一个全局组件, Vue的组件是有销毁机制的,比如条件渲染,
路由跳转时 组件都会经历销毁
, 再次回到页面时,又会回到 重生
,
这一过程保证了生命周期钩子函数各个过程都会在这一生命周期中执行.
假如有这样一个场景:我们当前所处在A组件,当我们跳转到B组件时(A组件被销毁,B组件被创建)
但是,当我们又从B组件回到A组件时(B组件被销毁,A组件被创建
这时,我们辛辛苦苦获取的数据 滑动的页面 会因为组件的销毁 重生 而 归零
,这影响了交互的体验, 所以 keep-alvie出现了, 可以帮助我们缓存想要缓存的组件实例, 只要用keep-alive 包裹
你想要缓存的组件实例, 这个时候, 组件创建之后,就不会再进行 销毁, 组件数据和状态得以保存
keep-alive使用方法一:
首先在定义路由的时候配置 meta 字段,自定义一个KeepAlive字段作为该页面是否缓存的标记:
routes:[{
path: '/search',
name: 'search',
component: search,
meta: {
title: '搜索列表页',
keepAlive: true // 标记列表页需要被缓存
}
},
{
path: '/detail',
name: 'detail',
component: detail,
meta: {
title: '详情页',
// 详情页不需要做缓存,所以不加keepAlive标记
}
}]
由于<keep-alive>组件不支持v-if指令,所以我们在App.vue中采用两个<router-view>的写法,通过当前路由的keepAlive字段来判断是否对页面进行缓存
如果组件需要缓存就走keep-alive,如果组件不需要缓存就直接router-view
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
keep-alive使用方法二:
使用<keep-alive>提供的 exclude(排除) 或者 include(包括) 选项,此处我们使用 exclude ,在App.vue中:
<div id="app">
<keep-alive exclude="detail">
<router-view />
</keep-alive>
</div>
需要注意的是,一定要给页面组件加上相应的name,例如在detail.vue中:
<script>
export default {
name: 'detail', // 这个name要和keep-alive中的exclude选项值一致
...
}
</script>
这么写就代表了在项目中除了name为detail的页面组件外,其余页面都将进行缓存。
要明白一个道理:
如果组件没有被缓存,当重新打开时,此组建的生命周期会重新再来一遍;如果组件被缓存了,此时重新返回组件时生命周期不会重新再来一遍;
但如果要更新数据怎么办呢?
vue还提供了两个生命周期函数:actived,deactived
(actived当组件缓存之后,其他的生命周期不会走,但这个每次进去组件都触发,相当于激活组件)
(deactived当组件缓存之后,其他的生命周期不会走,但这个每次离开组件都触发,相当于使组件休眠)
但是,没有了销毁,也就失去了重生的环节, 我们失去了 原有的钩子函数, 所以keep-alive包裹的组件 都获取了另外两个事件 --如果缓存组件需要重新获取数据
***唤醒 activated重新唤醒休眠组件实例时 执行
***休眠 deactivated组件实例进入休眠状态时执行
还有需要注意的问题是: 被缓存的组件中如果还有子组件, 那么子组件也会一并拥有 激活和唤醒事件,并且这些事件会在同时执行
那么如何主动销毁缓存数据呢?
思路:keep-alive 的 include 里存的其实是一个 vuex 中的一个数据源(数据源保存的是路由名称),当关闭标签页时,这个数据源中的一项会被移除。这之前,我们在组件里监听到这个数据源的变化,如果此组件对应的路由(这个路由应在 mounted 的时候保存下来)已经不在数据源中了,那就应该销毁此组件(监听当前路由是否被移除缓存,如果移除缓存则需要销毁该组件,否则内容中的缓存组件会越来越来,影响使用性能;)。
具体代码实现:
创建一个mixin.js文件,然后引入到需要被动态缓存的路由组件中即可;
//路由缓存管理
export default{
computed:{
keepAliveConf(){
//所有缓存的路由的name
return this.$store.state.app.cachePage;
}
},
watch:{
//当关闭某一路由时,进行此组件的销毁
keepAliveConf(e){
//监听缓存列表的变化,如果缓存列表中没有当前的路由或组件则在缓存中销毁该实例
let name = this.$options.name;
if(!e.includes(name)){
this.$destory()
}
}
},
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)