vue keep-alive组件的使用以及原理介绍

本篇文章给大家带来的内容是关于vue keep-alive组件的使用以及原理介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

keep-alive

keep-alive是vue.js的内置组件,它能够把不活动的组件的实例保存在内存中,而不是直接的销毁,它是一个抽象组件,不会被渲染到真实dom中,也不会出现在父组件链中。
它提供了exclude和include两个属性,允许组件有条件的缓存。

使用

    

登录后复制

上面的comment组件会被缓存起来。

        export default{    data(){        reurn{            test:true        }    },    methods:{        abc(){            this.test=!this.test;        }    }}

登录后复制

点击button的时候coma组件和comb组件会发生切换,但这时候两个组件的状态会被缓存起来,假如说a和b组件中都有一个input标签,这时切换input标签的值不会改变。

props

keep-alive组件提供了include和exclude两个属性来进行有条件的缓存,二者都可以用逗号分隔字符串、正则表达式或则数组表示。

    //name名为a的组件会被缓存起来    //name名为a的组件将不会被缓存。

登录后复制

生命钩子

keep-alive提供了两个生命钩子,actived与deactived。
因为keep-alive会把组件保存到内存中,并不会销毁或则重新构建,所以不会调用组件的creted等方法,需要使用actived和deactived两个钩子判断组件是否处于活动状态。

立即学习“前端免费学习笔记(深入)”;

深入keep-alive组件的实现

created和destroyed钩子
created钩子会创建一个cache对象,用来作为缓存容器,保存Vnode节点。

created{    this.cache=Object.create(null);}

登录后复制

destroyed钩子则在组件销毁的时候清除cache缓存中的所有组件实例。

/* destroyed钩子中销毁所有cache中的组件实例 */destroyed () {    for (const key in this.cache) {        pruneCacheEntry(this.cache[key])    }},

登录后复制

接下来是render函数。

render () {    /* 得到slot插槽中的第一个组件 */    const vnode: VNode = getFirstComponentChild(this.$slots.default)    const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions    if (componentOptions) {        // check pattern        /* 获取组件名称,优先获取组件的name字段,否则是组件的tag */        const name: ?string = getComponentName(componentOptions)        /* name不在inlcude中或者在exlude中则直接返回vnode(没有取缓存) */        if (name && (        (this.include && !matches(this.include, name)) ||        (this.exclude && matches(this.exclude, name))        )) {            return vnode        }        const key: ?string = vnode.key == null        // same constructor may get registered as different local components        // so cid alone is not enough (#3269)        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')        : vnode.key        /* 如果已经做过缓存了则直接从缓存中获取组件实例给vnode,还未缓存过则进行缓存 */        if (this.cache[key]) {            vnode.componentInstance = this.cache[key].componentInstance        } else {            this.cache[key] = vnode        }        /* keepAlive标记位 */        vnode.data.keepAlive = true    }    return vnode}

登录后复制

首先通过getFirstComponentChild获取第一个子组件,获取该组件的name(存在组件名则直接使用组件名,否则会使用tag)。接下来会将这个name通过include与exclude属性进行匹配,匹配不成功(说明不需要进行缓存)则不进行任何操作直接返回vnode。

/* 检测name是否匹配 */function matches (pattern: string | RegExp, name: string): boolean {  if (typeof pattern === 'string') {    /* 字符串情况,如a,b,c */    return pattern.split(',').indexOf(name) > -1  } else if (isRegExp(pattern)) {    /* 正则 */    return pattern.test(name)  }  /* istanbul ignore next */  return false}

登录后复制

检测include与exclude属性匹配的函数很简单,include与exclude属性支持字符串如”a,b,c”这样组件名以逗号隔开的情况以及正则表达式。matches通过这两种方式分别检测是否匹配当前组件。

if (this.cache[key]) {    vnode.componentInstance = this.cache[key].componentInstance} else {    this.cache[key] = vnode}

登录后复制

接下来的事情很简单,根据key在this.cache中查找,如果存在则说明之前已经缓存过了,直接将缓存的vnode的componentInstance(组件实例)覆盖到目前的vnode上面。否则将vnode存储在cache中。
最后返回vnode(有缓存时该vnode的componentInstance已经被替换成缓存中的了)。
用watch来监听pruneCache与pruneCache这两个属性的改变,在改变的时候修改cache缓存中的缓存数据。

watch: {    /* 监视include以及exclude,在被修改的时候对cache进行修正 */    include (val: string | RegExp) {        pruneCache(this.cache, this._vnode, name => matches(val, name))    },    exclude (val: string | RegExp) {        pruneCache(this.cache, this._vnode, name => !matches(val, name))    }},

登录后复制

来看一下pruneCache的实现。

/* 修正cache */function pruneCache (cache: VNodeCache, current: VNode, filter: Function) {  for (const key in cache) {    /* 取出cache中的vnode */    const cachedNode: ?VNode = cache[key]    if (cachedNode) {      const name: ?string = getComponentName(cachedNode.componentOptions)      /* name不符合filter条件的,同时不是目前渲染的vnode时,销毁vnode对应的组件实例(Vue实例),并从cache中移除 */      if (name && !filter(name)) {        if (cachedNode !== current) {          pruneCacheEntry(cachedNode)        }        cache[key] = null      }    }  }} /* 销毁vnode对应的组件实例(Vue实例) */function pruneCacheEntry (vnode: ?VNode) {  if (vnode) {    vnode.componentInstance.$destroy()  }}

登录后复制

遍历cache中的所有项,如果不符合filter指定的规则的话,则会执行pruneCacheEntry。pruneCacheEntry则会调用组件实例的$destroy方法来将组件销毁。

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

以上就是vue keep-alive组件的使用以及原理介绍的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2731771.html

(0)
上一篇 2025年3月8日 00:31:43
下一篇 2025年3月8日 00:31:50

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 详解Three.js利用orbit controls插件(轨道控制)控制模型交互动作

    这篇文章主要给大家介绍了关于three.js利用orbit controls插件,也就是轨道控制来控制模型交互动作的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。 推荐手册:JavaS…

    编程技术 2025年5月1日
    000
  • vue.js将echarts封装为组件一键使用

    做项目的时候为了让数据展示的更加直观,总会用到图表相关的控件,而说到图表控件第一时间当然想到echarts这个开源项目,而它不像iview、element-ui这些组件使用起来那么便捷,需要绕一个小弯,为了图方便于是对echarts进行了一…

    2025年5月1日
    000
  • D3.js 实现动态进度条实例

    d3 的全称是(data-driven documents),顾名思义可以知道是一个被数据驱动的文档。听名字有点抽象,说简单一点,其实就是一个 javascript 的函数库,使用它主要是用来做数据可视化的。如果你不知道什么是 javasc…

    2025年5月1日 编程技术
    000
  • Node.js爬取豆瓣数据实例

    这次给大家带来Node.js爬取豆瓣数据实例,Node.js爬取豆瓣数据的注意事项有哪些,下面就是实战案例,一起来看一下。 一直自以为自己vue还可以,一直自以为webpack还可以,今天在慕课逛node的时候,才发现,自己还差的很远。众所…

    2025年5月1日 编程技术
    000
  • React的使用:react框架的五大特点

    这篇文章给大家介绍的内容是关于react的使用:react框架的五大特点,有着一定的参考价值,有需要的朋友可以参考一下。 01. React 出现的时代背景 世界上的事情都有因才有果,一个框架的出现也必然离不开特定的时代背景。而对于 Rea…

    编程技术 2025年5月1日
    000
  • 使用echarts实现图表项目的注意点

    本篇文章给大家带来的内容是关于使用echarts实现图表项目的注意点,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 最近一段时间做了一个使用echarts的图表项目。由于理解API能力有限,使用起来并非畅通无阻。所谓好记性…

    编程技术 2025年5月1日
    000
  • 常用的echarts图表的实现代码

    本篇文章给大家带来的内容是关于常用的echarts图表的实现代码,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 本文代码基于ehcarts4.0开发 饼图 // 饼图配置项 var option = { series: […

    2025年5月1日 编程技术
    000
  • 九个常用的JavaScript图表库的介绍

    本篇文章给大家带来的内容是关于九个常用的javascript图表库的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 当前,数据可视化已经成为数据科学领域非常重要的一部分。不同网络系统中产生的数据,都需要经过适当的可视化…

    2025年5月1日 编程技术
    000
  • echarts如何优化数据视图dataView中的样式(代码示例)

    本篇文章给大家带来的内容是关于echarts如何优化数据视图dataview中的样式(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 在使用echart过程中,toolbox里有个dataView视图模式,里面的…

    2025年5月1日
    000
  • javascript主要用来干嘛

    javascript的作用:1、Web前端开发;2、服务端开发;3、移动应用开发;4、游戏开发;5、桌面应用开发。 JavaScript是一种广泛使用的编程语言,主要应用于Web前端开发,但也在其他多个领域展现出了强大的功能。以下是关于Ja…

    2025年5月1日
    000

发表回复

登录后才能评论