Мы разрабатываем подход к микро-интерфейсу с использованием Vue.js + Vuetify.js для создания нашего веб-клиента. Вся распределенная система состоит из множества микросервисов, которые выполняют некоторые задачи и производят некоторые данные. Основная идея состоит в том, что каждая служба также предоставляет инкапсулированный скомпилированный компонент (фрагмент) Vue, который отображает данные микросервиса и может быть извлечен и обработан клиентом по запросу во время выполнения. Итак, каждая служба имеет следующую структуру:
- ui
- fragments
- service specific source code
ui
просто содержит приложение Vue + Vuetify, созданное с помощью 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>
Этот подход не идеален, но в целом работает. В большинстве случаев связанные таким образом компоненты извлекаются, визуализируются и отображаются как часть клиента без каких-либо проблем. Однако в приведенном выше примере компонента мы используем Vuetify DatePicker
из примеров Vuetify. Визуализация этого фрагмента на стороне клиента приводит к полной сбою вкладки браузера, поэтому вкладка по-прежнему не несет ответственности. Я уже выяснил, что это вызвано слотом с ограниченной областью видимости, поэтому удаление определения следующего слота исправит сбой браузера:
<template v-slot:activator="{ on }">...
Также другие сложные компоненты Vuetify работают некорректно при использовании описанного подхода. Например, компоненты Vuetify Carousel
или Tabs
(вкладки) визуализируются без содержимого вкладок, как показано на следующем снимке экрана. :
Основные вопросы
Что может вызвать описанные проблемы с рендерингом при компиляции вложенных компонентов Vuetify? Каким будет правильный подход к компиляции компонентов Vue.js + Vuetify.js в пакет, чтобы избежать этих проблем?
Любые обсуждения были бы полезны!