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推荐 黄金广告位招租... 更多推荐

相关推荐

  • 详解js在html中的加载执行顺序

    js在html中的加载执行顺序 1.加载顺序:引入标记的出现顺序, 页面上的js代码是js的一部分,所以Javascript在页面装载时执行的顺序就是其引入标记的出现顺序, 标记里面的或者通过src引入的外部JS,都是按照其语句出现的顺序执…

    编程技术 2025年4月4日
    100
  • HTML和JS实现简单的计算器

    HTML和JS实现计算器功能的也是很容易的,本文主要和大家分享HTML和JS实现简单的计算器,希望能帮助到大家。 下面是代码:    nbsp;html>无标题文档 var result=””; function jisuan(num…

    编程技术 2025年4月4日
    100
  • 实现在HTML页面加载完毕后运行js方法

    本文主要和大家分享实现在HTML页面加载完毕后运行js方法,主要以代码的方法和大家分享,希望能帮助到大家。 Js方法: window.onload=function (){ var userName=”xiaoming”; alert(us…

    编程技术 2025年4月4日
    100
  • JavaScript实现获取远程的html到当前页面中

    今天做个项目,需要在当前的html页面中引用一个远程的html页面,百度了一下,发现一个非常好用的代码,这里分享给大家,有相同需求的小伙伴可以来看看 html代码 登录后复制 立即学习“Java免费学习笔记(深入)”; javascript…

    编程技术 2025年4月4日
    200
  • JavaScript模块优化

    给大家分享一下如何才能开发出更好的javascript模块和功能,有兴趣的朋友参考学习下吧。 不少人都曾经在 npm 上发布过自己开发的 JavaScript 模块,而在使用一些模块的过程中,我经常产生“这个模块很有用,但如果能 xxx 就…

    编程技术 2025年4月4日
    100
  • 适用于JavaScript开发人员的10个必备VSCode扩展

    如今,visual studio code无疑是最流行的轻量级代码编辑器。它确实从其他代码编辑器那借鉴了很多,最主要是从sublime和atom那里。然而它的成功关键是源于能提供更好的性能和稳定的表现。 另外,它还提供了如代码智能提示等开发…

    2025年4月2日 编程技术
    200
  • 提高 JavaScript 开发效率的高级 VSCode 扩展!

    如今,visual studio code无疑是最流行的轻量级代码编辑器。vs code的强大无疑来自于它的插件市场。多亏了开源社区,vs code现在几乎对所有的编程语言、框架和开发技术都有支持。 提供这种支持的方式是多样的,主要包括了为…

    2025年4月2日 编程技术
    200
  • 如何利用Vue实现拖拽穿梭框功能?四种方式介绍

    如何实现拖拽穿梭框功能?下面本篇文章给大家介绍一下vue实现拖拽穿梭框功能四种方式,希望对大家有所帮助。 【相关推荐:vue】 一、使用原生js实现拖拽 vue Lazyload .drag { background-color: skyb…

    2025年4月1日
    100
  • 聊聊MVVM模型在Vue中怎么应用

    理解MVVM模型 我们知道每一个 Vue 应用都是从创建一个新的实例开始的,根据 Vue2 的官方文档我们可以得知 Vue 的设计是得到了 MVVM 模型 的启发,所以就有了在我们创建 Vue 实例时,文档中经常使用vm这个变量名来表示 V…

    2025年4月1日 编程技术
    200
  • 浅析Vue3动态组件怎么进行异常处理

    vue3动态组件怎么进行异常处理?下面本篇文章带大家聊聊vue3 动态组件异常处理的方法,希望对大家有所帮助! 【相关推荐:vuejs视频教程】 动态组件有两种常用场景: 一是动态路由: 立即学习“前端免费学习笔记(深入)”; // 动态路…

    2025年4月1日
    100

发表回复

登录后才能评论