Сравнение с 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() |