我有一个门户网站,它以 vue 组件的形式提供不同的服务。我们将服务的所有设置保存在数据库中(包括存储该服务的路径 (=pfad))。通过这些数据,我们提供了应加载的所有活动服务的列表(有 50 多个服务,因此我们不想每次添加新服务时都编写新的导入)。
如果一个服务文件不存在,它也应该捕获错误(我们正在与多人一起开发这个工具,因此一个人会在数据库中声明一项新服务,但仅在他的功能分支上)。
我在
ServiceMain.vue
尝试了以下解决方案,但是导入的服务没有挂载。
HTML部分:
<template>
<b-row>
<b-col>
<!--Visible Services need the Service-Box so the user can click it. Import of the Service happens in teh Service-Box-->
<div>
<service-box v-for="service in filteredServices.slice((rowIdx - 1) * 3, rowIdx * 3)" :key="service.id"
:service="service" />
</div>
<!--Invisible Services should only get a component tag, they should not be visible to the user-->
<div
v-if="invisibleServices.length > 0"
style="!important display: none;">
<component
:is="componentFile"
v-for="(componentFile, index) in componentFilesOfInvisibleServices"
:key="'invisibleComponent_' + index"
/>
</div>
</b-col>
</b-row>
</template>
脚本部分:
export default {
name: "ServicesMain",
// components: {...},
data: function () {
return {
services: [],
visibleServices: [],
invisibleServices: [],
};
},
computed: {
componentFilesOfInvisibleServices() {
let files = [];
for (const invisibleService of this.invisibleServices) {
let componentName = invisibleService.pfad;
try {
let componentFile = import(`@/components/dialogs/${componentName}.vue`);
files.push(componentFile);
} catch (e) {
// later handel the Error if a file is not found
console.error(e)
}
}
return () => files;
},
},
mounted() {
this.getServices();
},
methods: {
getServices() {
ticketApi
.getTicketTypes()
.then(response => {
this.services = response.data;
this.visibleServices = response.data.filter(service => service.isVisible);
this.invisibleServices = response.data.filter(service => !service.isVisible && service.parentTicket === undefined);
// ...
})
.catch(error => {
console.error(error);
});
}
}
};
</script>
如果我使用在 :is="..." 中加载模块的函数,我会遇到无限循环
我还在 stackoverflow 上搜索并找到了以下线程,但没有一个对我有用或有解决方案。
这个解决方案理论上可行,但它是在没有过滤的情况下导入所有内容,我们需要在 vue-script 部分中过滤 te 组件的选项。
代码存在多个问题,以下解决方案适合我: HTML 部分不需要编辑。计算属性“componentFilesOfInvisibleServices”可以被删除,相反我们需要“componentFilesOfInvisibleServices”作为数据中的空数组。以下方法应该在其他代码之后的 then 块中的“getServices”中调用。
async loadComponentFilesOfInvisibleServices() {
this.componentFilesOfInvisibleServices = await Promise.all(
this.invisibleServices.map(async (service) => {
let componentName = service.pfad.substring(service.pfad.lastIndexOf('$') + 1);
const module = await import(`@/components/dialogs/${componentName}.vue`);
this.$options.components[componentName] = module.default;
return module;
})
);
},
我还需要在返回之前将“.default”添加到模块中,以便返回组件的默认值。
作为说明,在使用“.default”之前,我收到一条错误消息:
组件挂载失败:模板或渲染函数未定义
检查“模块”后,我认为您还必须使用“.default”。