Начните здесь | W3ref

Начните здесь

July 4, 2022
  • Фреймворки
  • JS
  • alpinejs
  • Начните здесь
Около 6 мин

Начните здесь

Создайте пустой HTML-файл где-нибудь на своем компьютере с именем, например: i-love-alpine.html

С помощью текстового редактора заполните файл следующим содержимым:

<html>
<head>
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body>
    <h1 x-data="{ message: 'Я ❤️ Alpine' }" x-text="message"></h1>
</body>
</html>

Откройте файл в веб-браузере, если вы видите Я ❤️ Alpine, вы готовы к бою!

Теперь, когда вы готовы поиграть, давайте рассмотрим три практических примера в качестве основы для обучения вас основам Alpine. К концу этого упражнения вы должны быть более чем готовы начать создавать что-то самостоятельно. Поехалиооооо.

<ul class="flex flex-col space-y-2 list-inside !list-decimal">
    <li><a href="#building-a-counter">Создание счетчика</a></li>
    <li><a href="#building-a-dropdown">Создание раскрывающегося списка</a></li>
    <li><a href="#building-a-search-input">Создание поискового ввода</a></li>
</ul>

Создание счетчика

Давайте начнем с простого компонента «счетчик», чтобы продемонстрировать основы прослушивания состояний и событий в Alpine — двух основных функциях.

Вставьте в тег <body> следующее:

<div x-data="{ count: 0 }">
    <button x-on:click="count++">Увеличение</button>

    <span x-text="count"></span>
</div>
<div class="demo">
    <div x-data="{ count: 0 }">
        <button x-on:click="count++">Увеличение</button>
        <span x-text="count"></span>
    </div>
</div>

Теперь, как вы можете видеть, добавив в этот HTML 3 бита Alpine, мы создали интерактивный компонент «счетчик».

Давайте кратко рассмотрим, что происходит:

Объявление данных

<div x-data="{ count: 0 }">

Все в Alpine начинается с директивы x-data. Внутри x-data, в простом JavaScript, вы объявляете объект данных, который Alpine будет отслеживать.

Каждое свойство внутри этого объекта будет доступно для других директив внутри этого HTML-элемента. Кроме того, при изменении одного из этих свойств все, что от него зависит, также изменится.

→ Подробнее о x-data

Давайте посмотрим на x-on и посмотрим, как он может получить доступ и изменить свойство count сверху:

Прослушивание событий

<button x-on:click="count++">Увеличение</button>

x-on — это директива, которую вы можете использовать для прослушивания любого события элемента. В данном случае мы прослушиваем событие click, поэтому наше событие выглядит как x-on:click.

Вы можете слушать другие события, как вы себе представляете. Например, прослушивание события mouseenter будет выглядеть так: x-on:mouseenter.

Когда происходит событие click, Alpine вызывает соответствующее выражение JavaScript, в нашем случае count++. Как видите, у нас есть прямой доступ к данным, объявленным в выражении x-data.

Вы часто будете видеть @ вместо x-on:. Это более короткий и удобный синтаксис, который предпочитают многие. Отныне в этой документации, скорее всего, будет использоваться @ вместо x-on:.

→ Подробнее о x-on

Реагирование на изменения

<h1 x-text="count"></h1>

x-text — это директива Alpine, которую вы можете использовать, чтобы установить текстовое содержимое элемента в результат выражения JavaScript.

В этом случае мы просим Alpine всегда следить за тем, чтобы содержимое этого тега h1 отражало значение свойства count.

Если это неясно, x-text, как и большинство директив, принимает в качестве аргумента простое выражение JavaScript. Так, например, вместо этого вы можете установить его содержимое: x-text="count * 2", и текстовое содержимое h1 теперь всегда будет в 2 раза больше значения count.

→ Подробнее о x-text

Создание раскрывающегося списка

Теперь, когда мы рассмотрели некоторые основные функции, давайте продолжим и рассмотрим важную директиву в Alpine: x-show, создав надуманный компонент "раскрывающийся список".

Вставьте следующий код в тег <body>:

<div x-data="{ open: false }">
    <button @click="open = ! open">Переключить</button>

    <div x-show="open" @click.outside="open = false">Контент...</div>
</div>
<div class="demo">
    <div x-data="{ open: false }">
        <button @click="open = ! open">Переключить</button>
        <div x-show="open" @click.outside="open = false">Контент...</div>
    </div>
</div>

Если вы загрузите этот компонент, вы должны увидеть, что "Контент..." по умолчанию скрыт. Вы можете включить их отображение на странице, нажав кнопку «Переключить».

Директивы x-data и x-on должны быть вам знакомы из предыдущего примера, поэтому мы пропустим эти объяснения.

Переключение элементов

<div x-show="open" ...>Контент...</div>

x-show — чрезвычайно мощная директива в Alpine, которую можно использовать для отображения и скрытия блока HTML на странице на основе результата выражения JavaScript, в нашем случае: open.

→ Подробнее о x-show

Прослушивание клика снаружи

<div ... @click.outside="open = false">Контент...</div>

Вы заметите что-то новое в этом примере: .outside. Многие директивы в Alpine принимают «модификаторы», которые прикрепляются к концу директивы и разделяются точками.

В этом случае .outside говорит Alpine вместо того, чтобы прослушивать клик ВНУТРИ <div>, слушать щелчок, только если он происходит ВНЕ <div>.

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

→ Подробнее о x-on modifiers

Создание поискового ввода

Давайте теперь создадим более сложный компонент и добавим несколько других директив и шаблонов.

Вставьте следующий код в тег <body>:

<div
    x-data="{
        search: '',

        items: ['foo', 'bar', 'baz'],

        get filteredItems() {
            return this.items.filter(
                i => i.startsWith(this.search)
            )
        }
    }"
>
    <input x-model="search" placeholder="Search...">

    <ul>
        <template x-for="item in filteredItems" :key="item">
            <li x-text="item"></li>
        </template>
    </ul>
</div>
<div class="demo">
    <div
        x-data="{
            search: '',

            items: ['foo', 'bar', 'baz'],

            get filteredItems() {
                return this.items.filter(
                    i => i.startsWith(this.search)
                )
            }
        }"
    >
        <input x-model="search" placeholder="Search...">

        <ul class="pl-6 pt-2">
            <template x-for="item in filteredItems" :key="item">
                <li x-text="item"></li>
            </template>
        </ul>
    </div>
</div>

По умолчанию все «элементы» (foo, bar и baz) будут отображаться на странице, но вы можете отфильтровать их, введя текст в поле ввода. По мере ввода список элементов будет меняться, отражая то, что вы ищете.

Здесь происходит совсем немного, так что давайте рассмотрим этот фрагмент по частям.

Многострочное форматирование

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

Привязка к инпутам

<input x-model="search" placeholder="Поиск...">

Вы заметите новую директиву, которую мы еще не видели: x-model.

x-model используется для "связывания" значения элемента ввода со свойством данных: "search" из x-data="{ search: '', ... }" в нашем случае.

Это означает, что каждый раз, когда значение ввода изменяется, значение «поиск» будет меняться, чтобы отразить это.

x-model способна на гораздо большее, чем этот простой пример.

→ Подробнее о x-model

Вычисляемые свойства с использованием геттеров

Следующее, на что я хотел бы обратить ваше внимание, это свойства items и filteredItems из директивы x-data.

{
    ...
    items: ['foo', 'bar', 'baz'],

    get filteredItems() {
        return this.items.filter(
            i => i.startsWith(this.search)
        )
    }
}

Свойство items должно говорить само за себя. Здесь мы устанавливаем значение items в массив JavaScript из 3 разных элементов (foo, bar и baz).

Интересная часть этого фрагмента — свойство filteredItems.

Обозначаемое префиксом get для этого свойства, filteredItems является свойством-получателем в этом объекте. Это означает, что мы можем получить доступ к filteredItems , как если бы это было обычное свойство в нашем объекте данных, но когда мы это делаем, JavaScript оценит предоставленную функцию внутри и вернет результат.

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

→ Подробнее о геттерах JavaScriptopen in new window

Теперь давайте заглянем внутрь геттера filteredItems и убедимся, что мы понимаем, что там происходит:

return this.items.filter(
    i => i.startsWith(this.search)
)

Это все обычный 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 на странице.

<ul>
    <template x-for="item in filteredItems">
        <li x-text="item"></li>
    </template>
</ul>

Первое, на что следует обратить внимание, это директива x-for. Выражения x-for принимают следующую форму: [item] in [items] где [items] — любой массив данных, а [item] — имя переменной, которая будет присвоена итерации внутри цикла.

Также обратите внимание, что x-for объявлен в элементе <template>, а не непосредственно в элементе <li>. Это требование использования x-for. Это позволяет Alpine использовать существующее поведение тегов <template> в браузере в своих интересах.

Теперь любой элемент внутри тега <template> будет повторяться для каждого элемента внутри filteredItems, и все выражения, оцениваемые внутри цикла, будут иметь прямой доступ к переменной итерации (в данном случае item).

→ Подробнее о x-for

Резюме

Если вы дочитали до этого момента, вы столкнулись со следующими директивами в Alpine:

  • x-data
  • x-on
  • x-text
  • x-show
  • x-model
  • x-for

Это отличное начало, однако есть еще много указаний, в которые можно вонзить зубы. Лучший способ познакомиться с Alpine — прочитать эту документацию. Не нужно прочесывать каждое слово, но если вы хотя бы просмотрите каждую страницу, вы будете НАМНОГО эффективнее при использовании Alpine.

Удачного кодирования!