Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keep-alive及其原理 #83

Open
Twlig opened this issue Mar 30, 2022 · 0 comments
Open

keep-alive及其原理 #83

Twlig opened this issue Mar 30, 2022 · 0 comments
Labels

Comments

@Twlig
Copy link
Owner

Twlig commented Mar 30, 2022

keep-alive

是什么?

  • keep-alive是一个Vue全局组件
  • keep-alive本身不会渲染出来,也不会出现在父组件链中
  • keep-alive包裹动态组件时,会缓存不活动的组件,而不是销毁它们

怎么用?

keep-alive接收三个参数:

  • include:可传字符串、正则表达式、数组,名称匹配成功的组件会被缓存
  • exclude:可传字符串、正则表达式、数组,名称匹配成功的组件不会被缓存
  • max:可传数字,限制缓存组件的最大数量

includeexclude,传数组情况居多

动态组件

<keep-alive :include="allowList" :exclude="noAllowList" :max="amount"> 
    <component :is="currentComponent"></component> 
</keep-alive>

路由组件

<keep-alive :include="allowList" :exclude="noAllowList" :max="amount">
    <router-view></router-view>
</keep-alive>

源码

组件基础

前面说了,keep-alive是一个Vue全局组件,他接收三个参数:

  • include:可传字符串、正则表达式、数组,名称匹配成功的组件会被缓存
  • exclude:可传字符串、正则表达式、数组,名称匹配成功的组件不会被缓存
  • max:可传数字,限制缓存组件的最大数量,超过max则按照LRU算法进行置换

顺便说说keep-alive在各个生命周期里都做了啥吧:

  • created:初始化一个cache、keys,前者用来存缓存组件的虚拟dom集合,后者用来存缓存组件的key集合
  • mounted:实时监听include、exclude这两个的变化,并执行相应操作
  • destroyed:删除掉所有缓存相关的东西

之前说了,keep-alive不会被渲染到页面上,所以abstract这个属性至关重要!

// src/core/components/keep-alive.js

export default {
  name: 'keep-alive',
  abstract: true, // 判断此组件是否需要在渲染成真实DOM
  props: {
    include: patternTypes,
    exclude: patternTypes,
    max: [String, Number]
  },
  created() {
    this.cache = Object.create(null) // 创建对象来存储  缓存虚拟dom
    this.keys = [] // 创建数组来存储  缓存key
  },
  mounted() {
    // 实时监听include、exclude的变动
    this.$watch('include', val => {
      pruneCache(this, name => matches(val, name))
    })
    this.$watch('exclude', val => {
      pruneCache(this, name => !matches(val, name))
    })
  },
  destroyed() {
    for (const key in this.cache) { // 删除所有的缓存
      pruneCacheEntry(this.cache, key, this.keys)
    }
  },
  render() {
      // 下面讲
  }
}

原文连接:

@Twlig Twlig added the Vue label Mar 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant