С этой статьей я хочу, чтобы вы отправились со мной в путешествие. И это путешествие связано с разработкой набора правил, позволяющих воспользоваться преимуществами одного из самых удивительных новых инструментов разработки программного обеспечения за последние два года.

Отказ от ответственности

Как архитектор, я иногда должен предоставить код, чтобы проиллюстрировать концепции, лежащие в основе идеи. Но не ждите, что я объясню, как и почему работает этот код. Вы найдете множество источников, чтобы сделать это лучше, чем я.

Введение

Когда я наткнулся на Svelte, я был очарован перспективой нового подхода к созданию веб-приложений. В первую очередь меня привлекла естественная привычка писать код в html, не беспокоясь о сложной структуре, как я привык в знакомых фреймворках, таких как React, Vue или Angular.

Я начал изучать документацию, последовал руководству и примерам и попробовал REPL, написав свое первое простое приложение - назовем его App.html.

Эти три блока легко обнаружить: любые элементы html, которые нужно нарисовать на экране, ‹style /› для определения соответствующего css и ‹скрипта /› , чтобы написать нужный код на JavaScript.

Но этот фрагмент нельзя запустить в браузере. У него есть сокращение для обработчика событий {clicked}, который необходимо предварительно перевести. И это то, что Svelte делает за кулисами. Он компилирует код в удобную для браузера среду, переводя ярлыки и помещая все части на свои места.

Давайте посмотрим на простую отправную точку index.html

<!doctype html>
<html>
<head>
 <meta charset='utf8'>
 <meta name='viewport' content='width=device-width'>
 <title>Conway's Game of Life</title>
 <link rel='stylesheet' href='global.css'>
 <link rel='stylesheet' href='bundle.css'>
 <script defer src='bundle.js'></script>
</head>
<body></body>
</html>

Чтобы обслуживать этот html-файл, Svelte необходимо скомпилировать и связать html и код JavaScript в bundle.js и код css в bundle.css. Вуаля!

Теперь мы можем с радостью приступить к кодированию - заполнив наш App.html тремя блоками. Svelte не оговаривает, как вы структурируете свой код. Это всего лишь инструмент, позволяющий вам найти свой путь в качестве кодировщика, а затем создавать чистый HTML-код и запускать его прямо в браузере. Давайте посмотрим, как мы можем разбить приложение на удобоваримые части.

Компоненты

Дорогая, я сжал приложение!

App.html теперь использует компонент Button.html (import Button…), который показывает его имя (export let name ) и распространяет событие on: click, обрабатываемое родительским компонентом с помощью {clicked}.
Чтобы легко отличить компоненты от собственных элементов html, их имена должны быть написаны с заглавной буквы, как в B utton… /›.

Это был очень простой пример - просто почувствовать запах ванили на османской кухне. Я предлагаю вам взглянуть на более сложный, чтобы увидеть его другой вкус.
Для этого я написал веб-приложение, демонстрирующее Игру жизни Конвея в простой визуализации. Если вас интересует полный исходный код, перейдите по ссылке. Вы также найдете получившуюся html-страницу в этом jsfiddle.

Сочинение

Эта «игра для одного игрока» состоит из трех разделов:

Как вы могли догадаться, все три раздела создают свои собственные компоненты, связанные вместе в App.html

То, что вы здесь видите, должно быть вам знакомо. Три компонента ‹Start /›, ‹Game /› и ‹Board /› получают некоторые входные данные и распространяют различные события, которые должны быть обрабатывается родительским приложением (App.html, см. ниже).

После этого довольно обширного вступления я хотел бы перейти к правилам, которые я обещал вам изложить. Причина в том, что Svelte - это инструмент, и, хотя он и рекомендует определенные варианты поведения, он не обеспечивает и не может обеспечить строгое использование, которое я вам предлагаю.

Правило №1: используйте управление потоком

Должно быть единое место, откуда можно будет контролировать поток приложения. Часто это корневой компонент, которому отправляются события интегрированных компонентов. Давайте посмотрим на другой пример, уменьшив App.html через призму компонента ‹Start /›:

Компонент ‹Start /› имеет поле ввода, привязанное к {Dimension}, и событие on: click {createBoard}, которое запускает ( отправляет) событие «create» родительскому компоненту с размером (длиной доски) в качестве аргумента.

Эта структура естественным образом позволяет информации перетекать от одного компонента к другому.

Правило № 2: Сохраняйте разделение интересов

Строго используя разные компоненты для разных задач, мы могли бы отдельно строить полезные блоки, которые будут хорошо интегрированы во многих различных ситуациях.

Как мы видели, такой компонент

  • предоставляет интерфейсы по умолчанию с HTML, CSS и данными (export let ‹var›), которые можно импортировать в любой другой компонент (import ‹Component› from…).
  • распространяет (on: click) или отправляет (on: click = {‹method›}) события родительскому компоненту, позволяя управлять потоком из одного места.

Но это еще не все.
В следующем фрагменте кода показан компонент Measure.html, который, как и следовало ожидать, может запускать и остановите таймер и верните разницу последнего прогона.
Во-первых, вы, как обычно, находите интерфейс компонента по умолчанию с html, css и скриптом.
Во-вторых, есть еще один тег ‹script› с добавленным свойством context = ”module”. И хотя код JavaScript в этом разделе хранится в том же файле, он не связан с интерфейсом компонента по умолчанию и должен быть реализован полностью независимо.

Его основная цель - отобразить логику, поддерживающую визуализацию компонента. В этом случае он предоставляет функцию createMeasure, возвращающую ее интерфейс, заключенный в объект JavaScript.

В следующем фрагменте показано использование этого компонента в App.html:

Теперь вы можете увидеть, как Measure.html обслуживает другие компоненты. Он создается App.html (createMeasure), запускается и останавливается компонентом Board через событие и, наконец, отображается в Game компонент через переменную showDiff.

Правило # 3: Поддерживайте состояние

Самым большим преимуществом Svelte является его реактивность. И это естественно достигается за счет

  • наблюдение за любой переменной интерфейса компонента по умолчанию (export let ‹variable›)
  • указание дополнительных наблюдаемых с помощью специального синтаксиса ($: var = ‹value›, см. ниже)

Как только какая-либо из этих наблюдаемых изменилась, каждый компонент, зависящий от одной из них, немедленно обновляется.

В качестве примера давайте посмотрим сквозь призму компонента Field, используемого компонентом Board и контролируемого компонентом App.

Компонент Board предоставляет один аргумент (export let rows, см. Ниже), используемый App.html для инициализации доски (‹Board {rows}… / ›). В любом случае (очистить, создать, перевернуть) переменная board устанавливается заново и запускает обновление строк через раздел наблюдаемых ($:… ).

Компонент Board создает экземпляр компонента Field в каждой ячейке открытых строк ({#each…}) и предлагает интерфейс компонента с методами для управления (create, clear, ) его состоянием.

Компонент Поле принимает три аргумента (индекс, состояние, изменено) и использует классы css ({colorState}, {colorCycle} , чтобы отразить состояние ячейки и то, изменилось ли оно или нет. Это, кстати, самый быстрый метод обновления элементов DOM на экране.
И снова наблюдаемые ($:… ) используются для поддержания актуальности этих переменных при изменении состояния ячейки.

Резюме

Svelte позволяет естественным образом кодировать html и заботится обо всех нечетких вещах в фоновом режиме.

Следуя трем золотым правилам, вы можете создавать многофункциональные и сложные веб-приложения:

  • №1: используйте управление потоком
    . Это подразумевает хороший дизайн приложения, разбив его на небольшие компоненты, независимо от того, предназначены ли они для визуализации или демонстрации некоторой логики, или и того, и другого. Поток запускается событиями в дочерних компонентах, которые распространяются на корневой компонент и возвращаются в дочерний компонент через наблюдаемые объекты.
  • №2: Сохраняйте разделение проблем
    . Строго отделите логику от представления, написав компоненты с методом создания, который возвращает свой интерфейс в объекте JavaScript, предлагаемом другим компонентам. Это заключает в себе вашу логику и подарит вам крепкий сон.
  • №3: Поддерживать состояние
    Звучит проще, чем есть на самом деле. Существует три вида переменных: аргументы компонента, наблюдаемые и свободные переменные.
    Svelte наблюдает за аргументами компонента, чтобы запускать обновления DOM, и поддерживает наблюдаемые объекты в актуальном состоянии на основе их входных данных. Строго отделяйте эти переменные от любых других, используемых для внутренней логики, и никогда не изменяйте их за пределами их области видимости.

Вывод

Svelte отлично справляется со своей задачей. Создав вышеупомянутое веб-приложение, я обнаружил, что это

  • очень быстро в прототипировании
  • очень маленький по размеру производственный код (~ 7 КБ в сжатом виде, включая html, css, JavaScript и sveltejs след)
  • очень эффективен, обновляя DOM напрямую и используя CSS везде, где это возможно

Компоненты Svelte - лучшие братья и сестры Веб-компонентов, спасибо, Рич Харрис за замечательный инструмент!

Надеюсь, вам понравилось читать, хорошо проводите время!

Ссылки, использованные в этой статье