Svelte for web components
Не так давно я смотрел фреймворки для написания веб-компонентов и в частности познакомился со Svelte в качестве инструмента написания веб-компонентов. Было создано всё тоже модальное окно, что и в случае LitElement & Stencil
Поехали
Svelte предлагает cli для генерации проекта.
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
npm run dev
Компонент Svelte похож на Vue компонент в том плане, что пишется однофайловый компонент с <script>
и <styles>
, где соотвественно пишется javascript и css соответственно.
Стили по-преженму взяты из Stencil версии компонента.
Логика получилась немного другой в отличии от версий LitElement и Stencil:
- две переменных
header
- заголовок окнаshow
- состояние открыто/закрыто
одна функция
closeModal
, которая генерирует событие закрытия окна.<script> import { createEventDispatcher } from "svelte"; const dispatch = createEventDispatcher(); export let header = ""; export let show = false; function closeModal(result) { show = false; dispatch("close", { result: result }); } </script>
Для отправки событий требуется функция createEventDispatcher из фреймворка, которая "под капотом" создаёт
CustomEvents
Шаблон получился весьма лаконичный. Можно разобраться без лишних слов.
{#if show}
<div class="dialog">
<div class="dialog__content">
<header>
<h2>{header}</h2>
</header>
<main>
<slot />
</main>
<footer>
<button class="dialog__ok-btn" on:click="{() => closeModal('ok')}">OK</button>
<button class="dialog__cancel-btn" on:click="{() => closeModal('cancel')}">
Отмена
</button>
</footer>
<div class="dialog__close-btn" on:click="{() => closeModal('close')}" />
</div>
</div>
<div class="overlay" />
{/if}
Svelte по-умолчанию не создаёт web components, их надо включить в rollup конфиге.
...
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file — better for performance
css: css => {
css.write('public/bundle.css');
},
customElement: true, // <==== включить веб компоненты
}),
...
После требуется добавить служебный тег с атрибутом тега разрабатываемого компонента.
<svelte:options tag="tyapk-modal"/>
Собственно и всё.
Пример использования модального окна
<tyapk-modal header="42">
<p>This is a slot. It can contain anything.</p>
</tyapk-modal>
Для прослушивания событий вместо стандартного addEventListener
следует использовать $on
. Удивительно не правда ли? Веб-компоненты же... (Хотя может я просто не успел постигнуть секретного секрета).
<script>
const modal = document.querySelector('tyapk-modal');
modal.$on('close', result => console.log('result', result));
</script>
Вместо заключения.
- Svelte - крутой. Фреймворк понравился, но он не создан для разработки веб-компонентов.
- Может я не успел чего понять, но ошибки... когда что-то пошло не так, весьма сложно разобраться, что именно. Куча кода вырезается, в итоге белый экран и пустая консоль(
This is a slot. It can contain anything.