广度搜索算法使用案例

169 阅读1分钟

背景

列表页面跳转详情页面。由于详情页面有一个加载较慢的通用业务组件,所以决定在列表页悄悄创建好这个业务组件,而不展示给用户,等进入详情页面再展示。

用户进入列表页后,百分之九十以上几率是会打开详情页面的。

在列表页创建好这个业务组件后,用户浏览多款产品详情时,都无需再创建该业务组件了。

方案

  1. 对列表页使用Keep-Alive组件
  2. 进入详情页后去拿取keep-alive缓存的列表页组件中的业务组件
  3. 将业务组件的$el插入到详情页面对应的dom位置。

实现

// 详情页面
mounted() {
  // 拿到keep-alive组件实例
  // keep-alive组件包裹了router-view组件
  const keepAliveComp = this.$options.parent;
  // 从组件的cache对象中拿到缓存的列表组件
  const productListComp = 
    Object.values(keepAliveComp.cache)
      .find(vnode => vnode.tag.endsWith('ProductList'))
      .componentInstance;
  // 注意,cache中缓存的对象都是vnode,取vnode.componentInstance
  
  // 现在要从列表组件中拿到(查找)业务组件
  // 使用广度优先的查找算法
  function bfs() {
    // 要查找的队列,先进先出
    // 从列表组件的子组件开始
    const comps = [...productListComp.$children];
    let comp;
    while (comps.length > 0) {
      // 从首部去一个组件进行判断
      comp = comps.shift();
      // 找到啦
      if (comp.$vnode.componentOptions.tag === 'BusinessComp') break;
      // 广度查找算法的核心,将当前节点的所有子节点加入到待检索队列尾部
      if (comp.$children?.length) {
        comps.push(...comp.$children);
      } else {
        // 没有找到
        if (comps.length === 0) {
          comp = null;
        }
      }
    }
    return comp;
  }
  
  const businessComp = bfs();
  // 插入到xx元素前面
  this.$el.insertBefore(businessComp.$el, this.$refs.xx)
}

总结

  1. 广度搜索算法实现真的很简单
  2. 一定要先理解广度搜索算法的规则。