阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      谈谈你对 Vue.js 中 keep-alive 的了解

      问题

      谈谈你对 Vue.js 中 keep-alive 的了解

      答案

      keep-alive可以实现组件的缓存,当组件切换时不会对当前组件进行卸载,常用的2个属性include/exclude,2个生命周期activated,deactivated

      对应源码

      core/components/keep-alive.js

      export default {
        name: 'keep-alive',
        abstract: true, // 抽象组件
      
        props: {
          include: patternTypes,
          exclude: patternTypes,
          max: [String, Number]
        },
      
        created () {
          this.cache = Object.create(null) // 创建缓存列表
          this.keys = [] // 创建缓存组件的key列表
        },
      
        destroyed () { // keep-alive销毁时 会清空所有的缓存和key
          for (const key in this.cache) { // 循环销毁
            pruneCacheEntry(this.cache, key, this.keys)
          }
        },
      
        mounted () { // 会监控include 和 include属性 进行组件的缓存处理
          this.$watch('include', val => {
            pruneCache(this, name => matches(val, name))
          })
          this.$watch('exclude', val => {
            pruneCache(this, name => !matches(val, name))
          })
        },
      
        render () {
          const slot = this.$slots.default // 会默认拿插槽
          const vnode: VNode = getFirstComponentChild(slot) // 只缓存第一个组件
          const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
          if (componentOptions) {
            // check pattern
            const name: ?string = getComponentName(componentOptions) // 取出组件的名字
            const { include, exclude } = this
            if ( // 判断是否缓存
              // not included
              (include && (!name || !matches(include, name))) ||
              // excluded
              (exclude && name && matches(exclude, name))
            ) {
              return vnode
            }
      
            const { cache, keys } = this
            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 // 如果组件没key 就自己通过 组件的标签和key和cid 拼接一个key
      
            if (cache[key]) {
              vnode.componentInstance = cache[key].componentInstance //  直接拿到组件实例
              // make current key freshest
              remove(keys, key) // 删除当前的  [b,c,d,e,a]   // LRU 最近最久未使用法
              keys.push(key) // 并将key放到后面[b,a]
            } else {
              cache[key] = vnode // 缓存vnode
              keys.push(key) // 将key 存入
              // prune oldest entry
              if (this.max && keys.length > parseInt(this.max)) { // 缓存的太多超过了max 就需要删除掉
                pruneCacheEntry(cache, keys[0], keys, this._vnode) // 要删除第0个 但是现在渲染的就是第0个
              }
            }
      
            vnode.data.keepAlive = true // 并且标准keep-alive下的组件是一个缓存组件
          }
          return vnode || (slot && slot[0]) // 返回当前的虚拟节点
        }
      }
      

      更多面试题

      如果你想了解更多的前端面试题,可以查看本站的WEB前端面试题 ,这里基本包涵了市场上的所有前端方面的面试题,也有一些大公司的面试图,可以让你面试更加顺利。

      面试题
      HTMLCSSJavaScript
      jQueryVue.jsReact
      算法HTTPBabel
      BootStrapElectronGulp
      Node.js前端经验相关前端综合
      Webpack微信小程序-

      这些题库还在更新中,如果你有不错的面试题库欢迎分享给我,我整理后放上来;人人为我,我为人人,互帮互助,共同提高,祝大家都拿到心仪的Offer!

      目录
      目录