Vue如何正确地复用异步组件?

DanoR 发布于 2019/06/06 15:32
阅读 607
收藏 0

【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”

请教一下,
有一个复用异步组件的需求,在Webpack环境下会异步下载模版后注册成组件:

JavaScript

// 异步下载的Vue模版
let template = (await import(`../view/${viewName}`)).default;
// 注册Vue组件
let component = Vue.component('myComponent', template);
// 手动创建Vue组件实例
let instance = new component();

HTML

<div>
	/* 显示实例instance的地方 */
	<component :is="viewNow" />
</div>

项目希望通过复用组件component,按需创建并管理实例instance,最后把实例instance显示到div下。

尝试一component元素,:is属性
结果很明显,根据文档和实际测试,:is不支持传入instance这样实例,翻遍文档也没发现类似的用法。

尝试二:不复用组件component,通过Vue.component复用模版template

项目当前使用中的方案。但当复用数十次甚至上百的时候,就感觉这种方案不是很优的处理,Vue.component也不是为此设计的,也不好管理销毁。

JavaScript

// times是动态次数
let component = Vue.component(`myComponent_${times}`, template);
viewNow = `myComponent_${times}`;

HTML

<keep-alive>
    <component :is="viewNow" />
</keep-alive>

尝试三:DOM操作appendChild

这是比尝试二更加暴力的方案,测试是可行的,但是直接操作DOM似乎会导致Mounter脱离Vue的监视,不清楚是否存在潜在的问题

HTML

<div class="compMain">
    /* 挂载后永远不变化的div */
	<div ref="mounter" />
</div>

JavaScript

// 上面的div
let mounter = this.$refs.mounter;
// 移除Mounter的子节点(子节点是Vue组件,可以保证只有一个)
if(mounter.children[0]) {
	mounter.removeChild(mounter.children[0]);
}
// 未渲染则先渲染
if(!instance.$el) {
	instance.$mount();
}
// 将渲染后的$el追加到Mounter下
mounter.appendChild(instance.$el);

 

综上各种尝试,并没有能令我放心的方案,所以在此请教各位大神,如何优雅正确地复用异步组件?万分感谢

加载中
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部