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>

Вместо заключения.

  1. Svelte - крутой. Фреймворк понравился, но он не создан для разработки веб-компонентов.
  2. Может я не успел чего понять, но ошибки... когда что-то пошло не так, весьма сложно разобраться, что именно. Куча кода вырезается, в итоге белый экран и пустая консоль(

This is a slot. It can contain anything.

Похожие записи