keep-alive简介
keep-alive是vue的一个组件,用来缓存其它组件,保留状态,避免重新渲染。用法比较简单,将组件作为keep-alive插槽就可以了。
<keep-alive>
<component>
<!-- 该组件将被缓存! -->
</component>
</keep-alive>
对于缓存的组件,多了activated(激活)和deactivated(失活)两个钩子。组件第二次进入不会走created和mounted钩子了,只会走activated
属性props
有三个属性
include- 可传字符串、正则表达式、数组。只有名称匹配的组件会被缓存。exclude- 可传字符串、正则表达式、数组。任何名称匹配的组件都不会被缓存。max- 数字。最多可以缓存多少组件实例。
<keep-alive :include="a" :max="2">
<router-view></router-view>
</keep-alive>
常与路由配合使用
router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存。可利用include/exclude针对性缓存组件
{
path: "/home",
name: 'home',
component: () => import(/* webpackChunkName: "home" */ '@/pages/home'),
meta: {
title: '首页',
keepAlive: true
},
},
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive && isRouterAlive"></router-view>
B->A要缓存,C-A要刷新,怎么办? 利用beforeRouteLeave钩子修改meta.keepAlive的属性。B组件里设置为true,C里设置false
// B
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = true;
next();
}};
原理
主要看看源码的缓存机制
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
// make current key freshest
// 命中缓存,移到尾部
remove(keys, key)
keys.push(key)
} else {
cache[key] = vnode
keys.push(key)
// prune oldest entry
//配置了max并且缓存的长度超了,从缓存中删除第一个
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
如果命中缓存,则直接从缓存中拿 vnode 的组件实例,采用LRU(Least recently used,最近最少使用)算法;如果没有命中将其放在缓存里面。 LRU算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
- 将新数据从尾部插入到
this.keys中; - 每当缓存命中(即缓存数据被访问),则将数据移到
this.keys的尾部; - 当
this.keys满的时候,将头部的数据丢弃;