背景
列表页面跳转详情页面。由于详情页面有一个加载较慢的通用业务组件,所以决定在列表页悄悄创建好这个业务组件,而不展示给用户,等进入详情页面再展示。
用户进入列表页后,百分之九十以上几率是会打开详情页面的。
在列表页创建好这个业务组件后,用户浏览多款产品详情时,都无需再创建该业务组件了。
方案
- 对列表页使用Keep-Alive组件
- 进入详情页后去拿取keep-alive缓存的列表页组件中的业务组件
- 将业务组件的$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)
}
总结
- 广度搜索算法实现真的很简单
- 一定要先理解广度搜索算法的规则。