当前位置: 首页 > news >正文

vue keep-alive组件

keep-alive

<keep-alive>是一个vue的内置组件,会缓存不活动的组件实例,他自身不会渲染一个DOM元素。直白说就是能在组件的切换过程中,将组件的状态保存在内存中,下次打开组件的时候不会重新渲染。

poprs:
include: 字符串或正则表达式,只有匹配的组件会被缓存。
     <keep-alive include="aaa">
        <component></component>
     </keep-alive>
     
exclude:字符串或正则表达式,任何匹配的组件都不会被缓存。
     <keep-alive include="bbb">
        <component></component>
     </keep-alive>
     组件名为bbb的组件不会被缓存。
复制代码
生命钩子
activated:当组件激活时调用。
deactivated:当组件关闭时调用。
注意:组件保存在内存当中,不会被重新创建,所以不会调用created等方法。
复制代码

keep-alive 的实现原理

created和destroyed钩子
/* created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点。*/
created () {
    /* 缓存对象 */
    this.cache = Object.create(null)
},

/* 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
}
复制代码

优先获取组件的name,没有则获取tag名,再将name或tag通过matches方法判断是否与include或exclude匹配,与exclude匹配成功则不需要缓存,直接返回vnode。与include匹配成功说明需要缓存,在判断cache中是否已经有缓存如果已经有缓存,则直接从缓存中获取,如果还没有缓存则保存到缓存中。

watch

用watch来监听include和exclude的变化。

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))
    }
},

/* 修正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()
  }
}复制代码

转载于:https://juejin.im/post/5b7f6ca151882542d950eb07

相关文章:

  • SQL Server CONVERT() 函数
  • JS一元操作符递增与递减
  • VUE - eslint - 笔记
  • jQuery文档操作之插入操作
  • SQL Server 导入excel时“该值违反了该列的完整性约束”错误
  • 使用一个公网地址配置多个Horizon安全服务器与连接服务器的方法
  • 为数据赋予超能力,阿里云重磅推出Serverless数据分析引擎-Data Lake Analyti
  • android 自定义view
  • 自己手撸一个符合Promise/A+的Promise
  • Zookeeper分布式集群原理与功能
  • 体积减少80%!释放webpack tree-shaking的真正潜力
  • CentOS7上Docker安装与卸载
  • webpack4.0各个击破(9)—— karma篇
  • day62:mysql主从配置
  • 网站服务器监控指标和日志收集
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【刷算法】从上往下打印二叉树
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • CSS实用技巧
  • django开发-定时任务的使用
  • gulp 教程
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Python学习笔记 字符串拼接
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 阿里云购买磁盘后挂载
  • 百度小程序遇到的问题
  • 闭包--闭包之tab栏切换(四)
  • 计算机常识 - 收藏集 - 掘金
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 小李飞刀:SQL题目刷起来!
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • #include
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (C++17) std算法之执行策略 execution
  • (附源码)计算机毕业设计大学生兼职系统
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (原創) 未来三学期想要修的课 (日記)
  • ***检测工具之RKHunter AIDE
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .Net 代码性能 - (1)
  • .NET 读取 JSON格式的数据
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET企业级应用架构设计系列之结尾篇
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @Builder用法
  • @PreAuthorize注解
  • [ C++ ] STL---string类的模拟实现
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [2013AAA]On a fractional nonlinear hyperbolic equation arising from relative theory
  • [AX]AX2012 R2 出差申请和支出报告