Первые шаги
-
Создайте где-нибудь на компьютере пустой HTML-файл с именем типа
i-love-alpine.html
-
Используя текстовый редактор, заполните файл таким содержимым:
-
Откройте свой файл в браузере — если вы увидите
Я ❤️ Alpine
, то можете продолжать!
Теперь, когда всё готово к работе, давайте рассмотрим три практических примера для обучения основам Alpine. К концу этого упражнения вы должны быть более чем готовы к созданию собственных проектов. Продолжим.
Создание счётчика
Давайте начнём с простого компонента «счётчик», чтобы продемонстрировать основы состояния и прослушивания событий в Alpine — двух базовых функций.
Вставьте следующее в тег <body>
:
Теперь вы можете видеть, что с помощью 3 кусочков Alpine, добавленных в этот HTML, мы создали интерактивный компонент «счётчик».
Давайте вкратце рассмотрим происходящее:
Объявление данных
Всё в Alpine начинается с директивы x-data
. Внутри x-data
на обычном JavaScript объявляется объект данных, который будет отслеживаться Alpine.
Каждое свойство этого объекта будет доступно другим директивам внутри данного HTML-элемента. Кроме того, при изменении одного из этих свойств меняется и всё, что на него опирается.
Давайте посмотрим на x-on
и разберёмся, как он может получить доступ к свойству count
для чтения и изменения:
Прослушивание событий
x-on
— это директива, которую можно использовать для прослушивания любого события на элементе. В данном случае мы слушаем событие click
, поэтому наш вариант выглядит как x-on:click
.
Можно прослушивать и другие события, как вы предполагаете. Например, прослушивание события mouseenter
будет выглядеть следующим образом: x-on:mouseenter
.
Когда происходит событие click
, Alpine вызывает связанное с ним JavaScript-выражение, в нашем случае count++
. Как видите, мы имеем прямой доступ к данным, объявленным в выражении x-data
.
Реагирование на изменения
x-text
— это директива Alpine, которую вы можете использовать для установки текстового содержимого элемента в результат выражения JavaScript.
В данном случае мы указываем Alpine на то, что содержимое тега span
всегда должно отражать значение свойства count
.
Если не понятно, то x-text
, как и большинство директив, принимает в качестве аргумента обычное JavaScript-выражение. Так, например, вместо этого можно задать его содержимое в виде: x-text="count * 2"
и текстовое содержимое span
теперь всегда будет в 2 раза больше значения count
.
Создание спойлера
Теперь, когда мы познакомились с базовой функциональностью, давайте продолжим и рассмотрим важную директиву в Alpine: x-show
, создав компонент «спойлер».
Вставьте в тег <body>
следующий код:
Если вы загрузите этот компонент, вы увидите, что «Содержимое…» по умолчанию скрыто. Для отображения скрытого содержимого нужно нажать кнопку «Переключить».
Директивы x-data
и x-on
должны быть знакомы вам по предыдущему примеру, поэтому мы опустим эти пояснения.
Переключение элементов
x-show
— чрезвычайно мощная директива в Alpine, которую можно использовать для отображения и скрытия блока HTML на странице на основе результата выражения JavaScript, в нашем случае: open
.
Прослушивание клика за пределами указанного элемента
В этом примере вы заметите кое-что новое: .outside
. Многие директивы в Alpine принимают «модификаторы», которые прикрепляются к концу директивы и разделяются точками.
В данном случае .outside
указывает Alpine на то, что вместо того, чтобы ожидать клик мыши ВНУТРИ <div>
, нужно ожидать клик мыши только в том случае, если он происходит ВНЕ <div>
.
Это удобный помощник, встроенный в Alpine, поскольку такая необходимость встречается часто, а реализовывать её вручную неудобно и сложно.
Создание поля поиска
Теперь построим более сложный компонент и введём несколько других директив и паттернов.
Вставьте в тег <body>
следующий код:
По умолчанию все «элементы» (foo, bar и baz) будут отображаться на странице, но вы можете отфильтровать их, введя текст в поле ввода. По мере ввода список элементов будет меняться в зависимости от того, что вы ищете.
Здесь происходит немало событий, поэтому давайте пройдёмся по этому фрагменту по частям.
Многострочное форматирование
Первое, на что хотелось бы обратить внимание, это то, что в x-data
теперь происходит гораздо больше событий, чем раньше. Для удобства написания и чтения мы разбили его на несколько строк в нашем HTML. Это совершенно необязательно, и мы ещё поговорим о том, как избежать этой проблемы, а пока оставим весь этот JavaScript непосредственно в HTML.
Привязка к полям
Вы заметите новую директиву, с которой мы ещё не встречались: x-model
.
x-model
используется для «привязки» значения входного элемента к свойству данных: в нашем случае «search» из x-data="{ search: '', ... }"
.
Это означает, что каждый раз, когда значение ввода изменяется, значение «поиск» будет меняться, чтобы отразить это.
x-model
способна на гораздо большее, чем этот простой пример.
Вычисляемые свойства с использованием геттеров
Следующий момент, на который я хотел бы обратить ваше внимание — это свойства items
и filteredItems
из директивы x-data
.
Свойство items
не требует пояснений. Здесь мы устанавливаем значение items
в массив JavaScript, состоящий из 3 различных элементов (foo, bar и baz).
Интересной частью этого фрагмента является свойство filteredItems
.
Обозначаемый префиксом get
для этого свойства, filteredItems
является «getter»-свойством в этом объекте. Это означает, что мы можем получить доступ к фильтруемым элементам, как если бы это было обычное свойство нашего объекта данных, но когда мы это сделаем, JavaScript выполнит запуск предоставленной функции и вернёт результат.
Вполне приемлемо отказаться от get
и просто сделать его методом, который можно вызывать из шаблона, но некоторые предпочитают более удобный синтаксис геттера.
Теперь заглянем в геттер filteredItems
и убедимся, что мы понимаем, что там происходит:
Это всё простой JavaScript. Сначала мы получаем массив элементов (foo, bar и baz) и фильтруем их, используя предоставленный обратный вызов: i => i.startsWith(this.search)
.
Передавая этот обратный вызов в filter
, мы говорим JavaScript, чтобы он возвращал только те элементы, которые начинаются со строки: this.search
, которая, как мы видели с x-model
, всегда будет отражать значение поля ввода.
Вы можете заметить, что до сих пор нам не приходилось использовать this
для ссылки на свойства. Однако, поскольку мы работаем непосредственно внутри объекта x-data
, мы должны ссылаться на любые свойства, используя this.[property]
вместо [property]
.
Потому что Alpine — это «реактивный» фреймворк. При каждом изменении значения this.search
части шаблона, использующие filteredItems
, будут автоматически обновляться.
Повторение элементов
Теперь, когда мы разобрались с внутренней частью нашего компонента, давайте поймем, что происходит в шаблоне, который позволяет нам перебирать filteredItems
на странице.
Первое, на что следует обратить внимание, — это директива x-for
. Выражения x-for
имеют следующий вид: [item] in [items]
, где [items]
— произвольный массив данных, а [item]
— имя переменной, которой будет присвоена итерация внутри цикла.
Также обратите внимание, что x-for
объявляется на элементе <template>
, а не непосредственно на <li>
. Это является обязательным условием использования x-for
. Это позволяет Alpine использовать существующее поведение тегов <template>
в браузере в своих интересах.
Теперь любой элемент внутри тега <template>
будет повторяться для каждого элемента внутри filteredItems
, а все выражения, вычисляемые внутри цикла, будут иметь прямой доступ к итерационной переменной (в данном случае item
).
Проверка знаний
-
Самая важная директива в Alpine.js…
-
Нажатие на какую из кнопок приведёт к переключению спойлера?
-
Синтаксис геттеров внутри объекта
x-data
выглядит как…
Итоги
Если вы дошли до этого момента, значит, в Alpine вы познакомились со следующими директивами:
- x-data
- x-on
- x-text
- x-show
- x-model
- x-for
Это отличное начало, однако есть ещё много нюансов, в которые стоит вникнуть. Лучший способ освоить Alpine — прочитать эту документацию. Не нужно прочёсывать каждое слово, но если вы хотя бы просмотрите каждую страницу, то будете НАМНОГО эффективнее использовать Alpine.
Приятного кодирования!