vue中keepalive,vue使用keep-alive缓存组件
最近最少使用算法算法全称为最近最少使用最近最少使用,核心思路是最近被访问的以后被访问的概率会变高,那么可以把之前没被访问的进行删除,维持一个稳定的最大容量值,从而不会导致内存溢出。
目录
vue的点火电极内置组件的使用也是使用了改算法,源码如下:实现一个自己的最近最少使用算法算法另一种
vue的keep-alive内置组件的使用也是使用了改算法,源码如下:
导出默认值{
名称:保持活动,
//抽象组件属性,它在组件实例建立父子关系的时候会被忽略,发生在初始生命周期的过程中
摘要:真的,
道具:{
//被缓存组件
包括:模式类型,
//不被缓存组件
排除:模式类型,
//指定缓存大小
最大值:[字符串,数字]
},
已创建(){
//初始化用于存储缓存的躲藏对象
这个。缓存=对象。创建(空);
//初始化用于存储虚拟节点键值的键数组
这个。keys=[];
},
销毁(){
对于(这个。躲藏中的常量键){
//删除所有缓存
pruneCacheEntry(this.cache,key,this。钥匙);
}
},
已安装(){
//监听缓存(包括)/不缓存(排除)组件的变化
//在变化时,重新调整躲藏
//pruneCache:遍历缓存,如果缓存的节点名称与传入的规则没有匹配上的话,就把这个节点从缓存中移除
这个手表( include ,val={
pruneCache(this,name=matches(val,name));
});
这个手表( exclude ,val={
pruneCache(this,name=!匹配(val,name));
});
},
render() {
//获取第一个子元素的虚拟节点
常量槽=这个.$ slots.default
const VNode:VNode=getFirstComponentChild(slot);
常量组件选项:VNodeComponentOptions=
vnode vnode .组件选项
if (componentOptions) {
//名称不在包含中或者在退出中则直接返回vnode,否则继续进行下一步
//检查模式
常量名称:string=getComponentName(组件选项);
const { include,exclude }=this
如果(
//不包括在内
(包括(!名字!匹配项(包括,名称)))
//排除
(排除名称匹配(排除,名称))
) {
返回虚拟节点
}
const { cache,keys }=this
//获取键,优先获取组件的名字字段,否则是组件的标签
常量键:字符串=
vnode.key==null
?//同一个构造函数可能被注册为不同的本地组件
//所以只有国际开发委员会是不够的(#3269)
组件选项Ctor.cid
(componentOptions.tag?`:${componentOptions.tag} `: )
:vnode.key
//-
//下面就是最近最少使用算法算法了,
//如果在缓存里有则调整,
//没有则放入(长度超过麦克斯,则淘汰最近没有访问的)
//-
//如果命中缓存,则从缓存中获取虚拟节点的组件实例,并且调整键的顺序放入键数组的末尾
如果(缓存[键]) {
vnode。组件实例=缓存[键].件实例
//使当前密钥最新
取出(钥匙,钥匙);
按键按钮(按键);
}
//如果没有命中缓存,就把虚拟节点放进缓存
否则{
cache[key]=vnode;
按键按钮(按键);
//删除最旧的条目
//如果配置了最大并且缓存的长度超过了这是麦克斯,还要从缓存中删除第一个
如果(这个。最大键数。长度解析int(this。最大)){
pruneCacheEntry(cache,keys[0],keys,this ._ vnode);
}
}
//保持活动状态标记位
vnode。数据。keepalive=true
}
返回vnode (slot slot[0]);
}
};
//移除键缓存
函数pruneCacheEntry(
缓存:VNodeCache,
键:字符串,
键:数组字符串,
当前?VNode
) {
const cached=cache[key]
如果(缓存(!当前 cached.tag!==current.tag)) {
缓存。组件实例。$ destroy()
}
缓存[键]=空
移除(钥匙,钥匙)
}
//移除方法(shared/util.js)
/**
*从数组中删除一个项目。
*/
导出函数remove (arr: Arrayany,item: any): Arrayany void {
如果(数组长度){
const index=arr.indexOf(item)
if (index -1) {
返回排列拼接(索引,1)
}
}
}
实现一个自己的LRU算法
最近最少使用算法算法的核心api(put get)和一个大小最大容器值,本质是类似队列放实现思路一是否存在,存在就先删除,再添加到队头2不存在,容量是否满了,删除最后一个队尾,再添加队头得到实现思路: 1.有就返回,同时插入队头2.没有返回-1 时间复杂度O(1)
最近最少使用算法级
构造者(大小){
this.cache=新地图()
this.size=size
}
put (key,val) {
//存在
if (this.cache.has(key)) {
//删除
this.cache.delete(键)
}否则{
//不存在,容量是否满了
如果(这个。size===这个。缓存。尺寸){
//删除最后一个
这个。缓存。删除(这个。缓存。keys().下一个()。值)//拿到队尾的元素
}
}
//插在队头
this.cache.set(key,val)
}
获取(密钥){
let val=this.cache.get(key)
如果(!val) {
返回-1
}
//访问了就需要放在队头
this.put(key,val)
返回值
}
}
另一种
//定义节点类
类节点{
构造函数(前一个,下一个,值,键){
this.pre=pre
this.next=下一个
这个值=值
this.key=key
}
}
//定义双向链表
类别双重列表{
构造者(头、尾){
this.head=头
this.tail=尾巴
}
}
图片类{
//构造函数,传入缓存容量
构造函数(最大值){
this.max=max
这个。Map=new Map();
let node=new Node(null,null,null,null);
这个。双列表=新双列表(节点,节点);
}
/**
* 获取缓存值
* 不存在返回-1,存在返回对应价值值,并将此节点移到尾巴
* @param {*} key key值
*/
获取(密钥){
let node=this.map.get(key)
如果(!节点){
return-1;
}否则{
this.moveNode2Tail(key,node);
返回节点.值
}
}
/**
* 插入缓存
* 1.不存在对应键值,加到尾巴
* 2.存在对应键值,更新此键值对应价值并提到尾巴
* 3.超出容量的话,去掉头部数据
* @param {*} key key值
* @param {*}值值
*/
放(键,值){
设node=this。地图。get(键);
如果(节点){
如果(!node.next){
节点值=值
返回;
}
节点。前。下一个=节点。接下来;
节点。下一个。pre=节点。pre
}
设新节点=新节点(null,null,value,key);
新节点。pre=这个。双列表。尾巴;
这个。双列表。尾巴。next=新节点;
这个。双列表。tail=新节点;
this.map.set(key,new node);
if(this.map.size this.max){
这个。地图。删除(这个。双列表。头。下一个。关键);
这个。双列表。头。下一个=这个。双列表。头。下一个。接下来;
这个。双列表。头。下一个。pre=这个。双列表。头;
}
}
//将节点移到尾巴
moveNode2Tail(key,node){
如果(!node.next){
返回;
}
//删除节点
节点。前。下一个=节点。接下来;
节点。下一个。pre=节点。pre
this.map.delete(键)
//新增尾巴节点
设newNode=新节点(null,null,node.value,key);
新节点。pre=这个。双列表。尾巴;
这个。双列表。尾巴。next=新节点;
这个。双列表。tail=新节点;
this.map.set(key,new node);
}
}
以上是LRU算法在Vue keep-alive内置组件中应用的详细内容。更多关于Vue LRU算法的信息,请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。