vue中的keep-alive用法指南

 更新时间:2024年10月10日 10:55:37   作者:张小瑜  
keep-alive是Vue中的一个内置组件,用于缓存非活动组件实例,避免重复渲染,优化性能,本文给大家介绍vue中的keep-alive用法指南,感兴趣的朋友一起看看吧

什么是keep-alive?

keep-alive是Vue的一个内置抽象组件,通常用于缓存动态组件或路由组件。被keep-alive包裹的组件在切换时不会被销毁,而是被缓存下来,下一次切换回这个组件时,会直接复用之前的实例,保持其状态。

<template>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</template>
<script>
export default {
  data() {
    return {
      view: 'homeComponent'
    };
  }
};
</script>

在这个例子中, homeComponent在被切换时不会被销毁,而是被缓存,当再次展示时,状态和数据都保持不变。

keep-alive重要的配置选项

1.include和exclude:用于控制哪些组件需要缓存,支持字符串、正则表达式或数组。

<keep-alive include="ComponentA, ComponentB" exclude="ComponentC">
  <router-view></router-view>
</keep-alive>

2.max:用于指定缓存的组件数量,当超出这个数量时,最久未使用的组件实例将被销毁。

<keep-alive :max="6">
  <router-view></router-view>
</keep-alive>

生命周期钩子

keep-alive还引入了两个新的组件生命周期钩子,用于处理缓存组件:

  • activated:当组件被激活时触发(即从缓存中恢复时)
  • deactivated:当组件被停用时触发(即被缓存时) 
export default {
  activated() {
    console.log('组件被激活了');
  },
  deactivated() {
    console.log('组件被缓存了');
  }
};

适用场景

  • 多页签(Tab)切换:在复杂的表单或多步操作场景中,用户频繁切换页面,如果使用keep-alive,切换回来的页面能保留之前输入的数据或操作状态。
  • 路由缓存:在Vue项目中,常常会在路由切换时希望保持组件的状态,如商品详情页、搜索页面等。 

keep-alive的核心原理

  • 缓存实例:当组件被第一次加载时,keep-alive会将组件的实例缓存起来。
  • 组件复用:当你切换到一个已经被缓存的组件时,keep-alive会从缓存中提取该组件的实例,而不是重新创建。
  • 生命周期管理:为了处理组件的激活和停用,keep-alive引入了activated和deactivated钩子,在组件进入或离开缓存时触发。 

核心原理:

  • 缓存实例:当组件被第一次加载时,keep-alive会将组件的实例缓存起来。
  • 组件复用:当你切换到一个已经被缓存的组件时,keep-alive会从缓存中提取该组件的实例,而不是重新创建。
  • 生命周期管理:为了处理组件的激活和停用,keep-alive引入了activated和deactivated钩子,在组件进入或离开缓存时触发。

keep-alive的源码解析

以下时抽取的部分原理代码:

export default {
  name: 'KeepAlive',
  abstract: true, // 这是一个抽象组件,表示它不会直接渲染到 DOM 上
  props: {
    include: patternTypes, // 要缓存的组件
    exclude: patternTypes, // 不缓存的组件
    max: [String, Number] // 最大缓存数
  },
  created () {
    this.cache = Object.create(null); // 缓存对象
    this.keys = []; // 用来记录缓存的顺序
  },
  destroyed () {
    for (const key in this.cache) {
      pruneCacheEntry(this.cache, key, this.keys);
    }
  },
  watch: {
    include (val) {
      pruneCache(this, name => matches(val, name));
    },
    exclude (val) {
      pruneCache(this, name => !matches(val, name));
    }
  },
  render () {
    const slot = this.$slots.default;
    const vnode = getFirstComponentChild(slot); // 获取第一个子组件
    if (vnode) {
      const componentOptions = vnode.componentOptions;
      const name = getComponentName(componentOptions);
      if (name && (
        (this.include && !matches(this.include, name)) ||
        (this.exclude && matches(this.exclude, name))
      )) {
        return vnode; // 如果不匹配 include/exclude,直接返回,不缓存
      }
      const key = vnode.key == null
        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
        : vnode.key;
      if (this.cache[key]) {
        vnode.componentInstance = this.cache[key].componentInstance; // 从缓存中取出实例
        remove(this.keys, key); // 移除旧的位置
        this.keys.push(key); // 重新放到最后,更新 LRU 位置
      } else {
        this.cache[key] = vnode; // 缓存新实例
        this.keys.push(key);
        // 如果超过最大缓存数,移除最早的实例
        if (this.max && this.keys.length > parseInt(this.max)) {
          pruneCacheEntry(this.cache, this.keys[0], this.keys, this._vnode);
        }
      }
      vnode.data.keepAlive = true; // 标记组件为 keep-alive
    }
    return vnode || (slot && slot[0]); // 返回 vnode
  }
};

 1.缓存机制

this.cache 是一个对象,用于存储已经缓存的组件实例

this.keys 是一个数组,用来记录缓存组件的顺序

2.组件的缓存和激活

在render函数中,Vue判断当前组件是否在inclue和exclude的范围内。如果匹配不到,则不进行缓存。

通过key标识组件,并将其与缓存实例关联。如果组件已经在缓存中,直接取出缓存的组件实例并复用。

3.LRU缓存策略

LRU缓存策略维持了一个有序的数据结构,记录了缓存项的使用顺序。当缓存达到容量限制时,它会移除最近最少使用的项,以便为新的数据腾出空间,常见的实现方式包括使用双向链表和哈希表的组合,来保持缓存项的顺序和快速访问。

当this.keys的长度超过max时,删除最早的缓存组件(即this.keys[0])

4.生命周期的管理

activated和deactivated生命周期钩子与keep-alive紧密相关,它们在组件被从缓存中激活和停用时触发。activated和deactivated钩子用于管理组件的激活和停用。

到此这篇关于vue中的keep-alive用法指南的文章就介绍到这了,更多相关vue keep-alive内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue-element-admin按钮级权限管控的实现

    vue-element-admin按钮级权限管控的实现

    开发离不开权限,不同的用户登录,根据不同的权限,可以访问不同的管理目录,本文主要介绍了vue-element-admin按钮级权限管控的实现,具有一定的参考价值,感兴趣的可以了解一下
    2022-04-04
  • vue 实现setInterval 创建和销毁实例

    vue 实现setInterval 创建和销毁实例

    这篇文章主要介绍了vue 实现setInterval 创建和销毁实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 使用jenkins一键打包发布vue项目的实现

    使用jenkins一键打包发布vue项目的实现

    这篇文章主要介绍了使用jenkins一键打包发布vue项目的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Vue nextTick的原理解析

    Vue nextTick的原理解析

    这篇文章主要介绍了Vue nextTick的原理解析,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-04-04
  • Vue动态添加表单的实现方法

    Vue动态添加表单的实现方法

    在Vue.js应用中,动态表单是一个常见的需求,尤其是当表单字段的数量和类型需要根据用户输入或系统状态动态变化时,本文将详细介绍如何在Vue中实现动态表单的创建,并通过多个示例展示具体的实现方法,需要的朋友可以参考下
    2024-09-09
  • Vue组件传值方式(props属性,父到子,子到父,兄弟传值)

    Vue组件传值方式(props属性,父到子,子到父,兄弟传值)

    这篇文章主要介绍了Vue组件传值方式(props属性,父到子,子到父,兄弟传值),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Vue element实现权限管理业务流程详解

    Vue element实现权限管理业务流程详解

    目前本人再使用vue-element-admin项目时都是通过直接删除一些用不上的路由来进行侧边栏的清除,但是其实有一个更加好的办法来对项目的侧边栏显示的内用进行管理,就是权限管理,其实也不知道这个方法好不好,原理上来说时跟直接删除该路由的方式时一样的
    2022-08-08
  • Element-ui table中过滤条件变更表格内容的方法

    Element-ui table中过滤条件变更表格内容的方法

    下面小编就为大家分享一篇Element-ui table中过滤条件变更表格内容的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Vue3在css中使用v-bind绑定js/ts变量(在scss和less中使用方式)

    Vue3在css中使用v-bind绑定js/ts变量(在scss和less中使用方式)

    v-bind是Vue.js中的一个核心指令,用于在Vue组件或DOM元素上绑定数据属性,下面这篇文章主要给大家介绍了关于Vue3在css中使用v-bind绑定js/ts变量的相关资料,也可以在scss和less中使用方式,需要的朋友可以参考下
    2024-04-04
  • vue实现多级侧边栏的封装

    vue实现多级侧边栏的封装

    这篇文章主要为大家详细介绍了vue实现多级侧边栏的封装,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07

最新评论