Vue Keep-alive使用
keep-alive是vue原生自带的,用来缓存组件的
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>
<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包裹的组件 都获取了另外
还有需要注意的问题是: 被缓存的组件中如果还有子组件, 那么子组件也会一并拥有 激活和唤醒事件,并且这些事件会在同时执行
那么如何主动销毁缓存数据呢?
思路: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() } } }, }