zoukankan      html  css  js  c++  java
  • 如何实现keep-alive

    路径:

    路径

    由上图可知,keep-alive.js导出的对象(如下),作为一个属性将会注入到Vue.options.components中。

    const patternTypes = [String, RegExp, Array]
    export default {
      name: 'keep-alive',
      abstract: true,
    
      props: {
        // 根据组件 name 进行匹配。如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
        include: patternTypes,  // 匹配的组件将会被缓存
        exclude: patternTypes,  // 匹配的组件不会被缓存
        max: [String, Number]   // 最大缓存组件数
      },
    
      created () {
        // 保存缓存的组件
        this.cache = Object.create(null)
        // 保存缓存的组件的key
        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 () {
        // this.$slots.default 包含了所有没有被包含在具名插槽中的节点
        // 这里取得第一个子组件
        const vnode = getFirstComponentChild(this.$slots.default)
        const componentOptions = vnode && vnode.componentOptions
    
        if (componentOptions) {
          // check pattern
          const name = getComponentName(componentOptions)
          // 如果 componentName 没有作为keep-alive被包含进来,直接返回
          if (name && (
            (this.include && !matches(this.include, name)) ||
            (this.exclude && matches(this.exclude, name))
          )) {
            return vnode
          }
    
          const { cache, keys } = this
          const key = vnode.key == null
            // 相同的构造器(constructor)可能会注册为不同的本地组件,所以仅有一个 cid 是不够的(#3269)。
            ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
            : vnode.key
          
          if (cache[key]) { // 如果已经缓存了,需要保持当前的key 是最新的
            vnode.componentInstance = cache[key].componentInstance
            remove(keys, key)
            keys.push(key)
          } else {  // 否则,进行缓存并更新keys数组。
            cache[key] = vnode
            keys.push(key)
            // 缓存组件超出最大值,将队首的组件销毁(先进先出)
            if (this.max && keys.length > parseInt(this.max)) {
              pruneCacheEntry(cache, keys[0], keys, this._vnode)
            }
          }
    
          vnode.data.keepAlive = true
        }
        return vnode
      }
    }
    
    <div id="app">
      <keep-alive>
          <router-view v-if="$route.meta.keepAlive">
            <!-- 这里是会被缓存的视图组件 -->
          </router-view>
      </keep-alive>
    
      <router-view v-if="!$route.meta.keepAlive">
        <!-- 这里是不被缓存的视图组件 -->
      </router-view>
    </div>
    
  • 相关阅读:
    SpringCloudAlibaba
    wechat kill
    使用vscode调试 pomelo
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD 分析编辑页面添加搜索页面
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD添加视图(View)
    Terry的学习笔记ASP.NET MVC 4 简介
    正则表达式总结
    自己编写的 objectDataSource 配合 GridView 实现分页
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD 从控制器访问模型中的数据
    Terry的学习笔记ASP.NET MVC 4 HELLO WORLD添加控制器(Controller)
  • 原文地址:https://www.cnblogs.com/fayin/p/8058908.html
Copyright © 2011-2022 走看看