Содание Web components на Vue 3
Можно написать на Vue 3 какой-нибудь полезный компонент и захотеть дать возможность использовать его не только в Vue проектах, но и на любых других фронтендах. Сделать это несложно через регистрацию его как web component, или подключение «микро-фронтендом». Оба варианта будут рассмотрены ниже.
Рассмотрим универсализацию на примере release-timeline
При разработке используем Vite с двумя конфигами — один непосредственно для разработки и запуске в Dev режиме на сервере Vite, другой — для билда библиотеки.
// package.json
"scripts": {
"build": "vite build",
"build:lib": "vite --config vite.config-lib.ts build"
В vite.config-lib.ts указана точка входа index.ts
и также указано, чтобы не включать в бандл дистрибутив Vue.
Самое интересное это именно точка входа index.ts. Она общая для всех режимов — npm vue библиотека, web component и микро-фронтенд. Это очень удобно при разработке и сборке.
import { createApp, defineCustomElement } from "vue";
import { DefaultOptions } from "./options";
import ReleaseTimelineCE from "./ReleaseTimeline.ce.vue";
import ReleaseTimeline from "./ReleaseTimeline.vue";
import App from "./App.vue";
if (globalThis.window) {
window.customElements.define("release-timeline", defineCustomElement(ReleaseTimelineCE));
}
function mountRT(initOptions) {
const app = createApp(App, { initOptions });
app.mount("#release-timeline");
}
export { ReleaseTimeline, DefaultOptions, mountRT };
export {};
Микро-фронтенд
В данном режиме используется вызов mountRT()
:
После этого произойдет монтирование приложения на `
`Vue 3 пакет
Библиотека экспортирует на 16 строке все нужные модули — ReleaseTimeline
и DefaultOptions
, и их можно сразу использовать в коде через импорт, как обычно.
Web component
С веб компонентами два момента:
В качестве пропсов они принимают только строки. Поэтому если вам нужно передать массив или объект (как в нашем случае), нужно его либо сериализовать и десериализовать, либо передать опции через общий контекст —
window
. Не очень красиво, но работает.При подключении в проект как Vue библиотеку, CSS стили нужно импортировать отдельно. Практически всегда. В случае веб компонент стили итегрируются и не доступны для изменения снаружи, за исключением CSS переменных.
Чтобы организовать работу со стилями нам нужен ReleaseTimeline.ce.vue
:
Это обертка на ReleaseTimeline
, которая, во-первых, обрабатывает параметры, переданные через window
, и во-вторых, работает со стилями.
Если бы главный компонент был один, мы могли бы поместить все стили в его style
секцию. Но Vite при билде не собирает стили из компонент-потомков, поэтому приходится это делать вручную в ReleaseTimeline.ce.vue
. Именно поэтому пришлось размещать их в отдельных файлах и использовать SCSS импорт. Суффикс ce.vue
говорить сборщику использовать специальный режим для `custom elements`.
Возвращаясь к index.ts
, — на 7 строке мы проверяем, что находимся в браузере (на случай использования в SSR/SSG средах — например, при сборке VitePress
), и затем регистрируем веб компонент.
В итоге, для превращения Vue компонента в web component, нужна простая обертка и несколько строк в index.ts
Вот здесь — wc-demo — можно посмотреть код html страницы, чтобы увидеть пример использования release-timeline
как веб компонента. Дистрибутив Vue подключается отдельно.
Наш Telegram-канал о Vue и фронтенд-разработке: @vuefaq и вебсайт: Vue‑FAQ.org.