Сравнение с Vue¶
Solid не испытывает особого влияния Vue с точки зрения дизайна, но по подходу они сопоставимы. Они оба используют прокси в своей реактивной системе с автоматическим отслеживанием чтения. Но на этом сходство заканчивается. Компактное определение зависимостей в Vue просто вливается в менее компактную систему виртуального DOM и компонентов, в то время как Solid сохраняет детализацию вплоть до прямого обновления DOM.
Vue ценит простоту, а Solid - прозрачность. Хотя направление развития Vue с выходом Vue 3 и введением API композиции больше соответствует подходу Solid. Со временем, в зависимости от дальнейшего развития, эти библиотеки могут еще больше сблизиться. Большинство примеров и ссылок на Vue в этом разделе будут сделаны в отношении API композиции, представленного в Vue 3.
Шаблонные компоненты против функциональных компонентов¶
С точки зрения фронтенд-фреймворков компоненты служат для разделения пользовательского интерфейса на различные многократно используемые части кода, большинство приложений и сайтов в настоящее время представляют собой деревья вложенных компонентов.
Vue¶
В Vue установка компонентов может осуществляться двумя способами: с помощью шаблонов или с помощью функций рендеринга. Наиболее распространенным на данный момент является использование шаблонов, например, так:
1 2 3 4 5 6 7 8 9 10 11 | |
Если вы не знакомы с ним, то это синтаксис шаблонов, используемый с API композиции в Vue. HTML используется в теге <template></template>, а Javascript или Typescript - в теге <script></script>. Для стилизации используется третий тег, который называется <style></style>.
Solid¶
Solid использует только один вид компонентов - компонент-функцию. В отличие от Vue, в Solid нет различных синтаксисов, есть только один. Все компоненты и страницы в Solid представлены компонентами функций. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Вот как выглядит компонент функции. Обратите внимание на основное различие между ним и синтаксисом шаблона, используемым в Vue. Также есть небольшие отличия в использовании переменных в HTML-части, например, одна фигурная скобка вместо двух. Синтаксис объявления и изменения переменных с состоянием также отличается, подробнее об этом позже.
Reactivity and Statefulness¶
В Vue есть две ключевые функции, которые используются для объявления и управления реактивными и государственными значениями, ref() и reactive(), причем ref() может хранить такие примитивы, как булевы числа, строки и объекты, а reactive() - только объекты. В Solid имеются аналогичные функции, а именно createSignal() и createStore() соответственно. В этой части мы рассмотрим их различия в синтаксисе и методах обновления.
Синтаксис функций ref() и createSignal() или reactive() и createStore() не сильно отличается, фактически reactive() и createStore() похожи по синтаксису при обращении к значениям, но отличаются при изменении значений, например
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
С другой стороны, ref() и createSignal() отличаются как установкой, так и доступом к своим значениям, например:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Ниже более подробно рассмотрено, как может отличаться синтаксис в простом приложении со счетчиком.
Vue¶
В Vue для работы с состоянием компонента Vue можно использовать функции ref() и reactive(). В некоторых случаях reactive() может служить простой альтернативой управлению состоянием вместо использования VueX. Вот краткий фрагмент того, как это может выглядеть:
1 2 3 4 5 6 | |
Выше мы создали наш магазин с помощью функции reactive().
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Выше представлен компонент, в который импортирован магазин, чтобы изменить одно из значений в нем.
1 2 3 4 5 6 7 8 9 | |
Это отдельный компонент, который будет отображать значение графа даже при его изменении.
Вы также можете использовать другие реактивные состояния, такие как ref() и computed().
1 2 3 4 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Обратите внимание на комментарии в коде и на то, как меняется реактивность при использовании reactive() или ref().
Solid¶
В Solid мы можем сделать нечто подобное, используя примитивы createStore() и createSignal(). Помните, что createStore() принимает в качестве значений только объекты, а createSignal() может принимать булевы значения, объекты, строки и числа. Вот краткий пример того, как это может выглядеть, если вы решите использовать createStore() в качестве простого решения для управления состоянием
1 2 3 4 | |
Выше мы создали магазин с помощью функции createStore() в Solid.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Приведенный выше компонент просто импортирует функции setter и getter магазина, чтобы установить и получить текущее состояние магазина.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Это отдельный компонент, который служит для отображения текущего состояния хранилища и значений в нем.
Вы также можете использовать примитив createSignal(), например, так:
1 2 3 4 5 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Обратите внимание на комментарии в коде и на то, как меняется реактивность при использовании createStore() или createSignal().
Условный рендеринг¶
В мире фронтенд-фреймворков условный рендеринг - это рендеринг компонента или узла только при выполнении определенного условия.
Например, допустим, вы хотите, чтобы вводимая форма отображалась только в том случае, если пользователь нажимает на кнопку show/hide, и скрывалась, если пользователь нажимает на эту кнопку еще раз. В этом случае можно просто использовать булевую переменную под названием isShowing, и если ее значение равно true, то форма будет показана, а если false - то скрыта.
Хорошо, теперь, когда мы кратко рассмотрели концепцию условного рендеринга, давайте посмотрим, как это может выглядеть в Vue, а затем в Solid.
Vue¶
Если у вас есть опыт работы с Vue, я уверен, что вы должны быть знакомы с директивами v-if, v-else и v-else-if. Она используется для условного рендеринга самого себя и всего того, что она оборачивает. Ее можно использовать следующим образом:
1 2 3 4 5 | |
В приведенном выше блоке кода Vue is awesome выводится, если vueVotes больше, чем solidVotes, а Solid is more awesome 😁 выводится, если наоборот, и в конце есть else, если ни то, ни другое не так.
Solid¶
В Solid есть компоненты, подобные этим, которые очень упрощают условный рендеринг и выглядят гораздо чище. Это компоненты Show, Switch и Dynamic. Давайте рассмотрим, как их можно использовать.
Show¶
Этот компонент может использоваться для работы с простыми булевыми значениями и выражениями.
1 2 3 4 5 6 | |
В приведенном выше коде, если условие when не выполнено, то будет отрисован fallback.
Switch¶
Эта функция может быть использована для работы с переключателями и более сложными выражениями, в которых используется более двух взаимоисключающих исходов.
1 2 3 4 5 6 7 8 | |
В приведенном выше коде, если ни одно из условий when не выполнено, будет отрисован fallback.
Dynamic¶
Этот встроенный компонент может быть использован для отрисовки элементов из карты ключей и компонентов/элементов. Он принимает свойство component и динамически отрисовывает любой переданный ему элемент или компонент. Вы можете воспользоваться этим преимуществом, передавая компонент динамически, используя карту и ключ. Приведем небольшой пример, демонстрирующий его использование
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
В приведенном выше коде выбор компонента для визуализации зависит от выбранного выпадающего варианта, который служит ключом к карте компонентов.
Не стесняйтесь экспериментировать и использовать те встроенные компоненты, которые вам удобны.
Рендеринг списков¶
Очень часто разработчики сталкиваются с тем, что чаще всего используют списки. В том случае, если в приложении требуется итерация и рендеринг объектов, относящихся к спискам или массивам, некоторые фреймворки предлагают достаточно простой способ сделать это. Давайте рассмотрим, как это делают Vue и Solid.
Vue¶
В Vue для вывода списка или массива элементов используется директива for, например, так:
1 | |
В приведенном выше коде Vue отображает столько элементов <li></li>, сколько элементов содержится в массиве items.
Solid¶
В Solid компонент <For> является наилучшим способом циклического перемещения по массиву объектов. При изменении массива компонент <For> обновляет или перемещает элементы в DOM, а не создает их заново. Рассмотрим пример с использованием компонента <For>
1 2 3 4 5 | |
В компоненте <For> есть одно свойство, называемое each, в которое вы передаете массив, по которому хотите выполнить цикл.
Vue vs. Solid¶
Приведем таблицу различий между хуками в Vue и хуками в Solid.
| Vue(composition) | Vue(options) | Solid |
|---|---|---|
onMounted() | mounted | onMount() |
onUnmounted() | unmounted | onCleanup() |
ref(), shallowRef() | data | createSignal() |
reactive() | data | createStore() |
computed() | computed | createMemo() |
watchEffect() | this.$watch() or watch | createEffect() |