我们正在使用 Vue.js + Vuetify.js 开发一种微前端方法来构建我们的网络客户端。整个分布式系统由许多微服务组成,这些微服务执行一些任务并产生一些数据。主要思想是每个服务还提供一个封装编译的Vue组件(片段),显示微服务的数据,并且可以在运行时由客户端按需获取和渲染。所以每个服务都有以下结构:
- ui
- fragments
- service specific source code
ui
仅包含使用vue/cli
. 该片段比普通的 Vue 组件更重要,如下所示:
<template>
<v-menu
...
>
<template v-slot:activator="{ on }">
<v-text-field
...
v-on="on"
></v-text-field>
</template>
<v-date-picker v-model="date" no-title @input="menu1 = false"></v-date-picker>
</v-menu>
</template>
<script>
export default {
name: 'HelloWorld'
...
};
</script>
这个组件被编译成一个包helloworld.umd.min.js
,并从服务中作为静态文件提供:
vue-cli-service build --mode production --target lib --inline-vue --formats umd-min --watch --name helloworld ./src/components/HelloWorld.vue
在客户端,我们通过创建一个<script src="http://localhost:2000/helloworld.umd.min.js">
带有指向服务片段的 URL 的标签来在运行时将片段绑定到特定页面上。当浏览器获取包时,HelloWorld
组件可用并使用 Vue 动态组件呈现,如下所示:
// component is the HellowWorld bundled component
<component :is="component" v-bind="bindProps"></component>
这种方法并不完美,但通常有效。在大多数情况下,如此捆绑的组件被提取、渲染和显示为客户端的一部分,没有任何问题。然而,在上面的示例组件中,我们使用了DatePicker
Vuetify 示例中的 Vuetify。在客户端渲染此片段会导致浏览器选项卡完全崩溃,因此该选项卡仍然不负责。我已经发现这是由作用域插槽引起的,因此删除以下插槽定义将修复浏览器崩溃:
<template v-slot:activator="{ on }">...
此外,其他复杂的 Vuetify 组件也无法通过使用所描述的方法正常工作。例如 VuetifyCarousel
或Tabs
组件(选项卡)是没有选项卡内容的渲染端,如下面的屏幕截图所示:
主要问题
编译嵌套的 Vuetify 组件会导致所描述的渲染问题是什么?将 Vue.js + Vuetify.js 组件编译成一个包以避免这个问题的正确方法是什么?
任何讨论都会有所帮助!