x-model и поля формы
Директива x-model связывает поле формы со свойством компонента в обе стороны. Пользователь вводит текст — свойство меняется; код меняет свойство — поле обновляется. Такую связь называют двусторонней привязкой.
Текстовое поле
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ title: '' }">
<input x-model="title" placeholder="Новая задача">
<p>Вы ввели: <span x-text="title"></span></p>
</div>Текст под полем повторяет ввод на каждое нажатие клавиши.
Форма списка дел
Теперь можно собрать форму без $refs. После добавления задачи поле очищается присваиванием title = '':
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<style>
.done { text-decoration: line-through; }
</style>
<div x-data="{
title: '',
tasks: [{ id: 1, title: 'Купить молоко', done: false }],
add() {
if (this.title.trim() === '') return;
this.tasks.push({ id: Date.now(), title: this.title.trim(), done: false });
this.title = '';
}
}">
<form @submit.prevent="add()">
<input x-model="title" placeholder="Новая задача">
<button>Добавить</button>
</form>
<ul>
<template x-for="task in tasks" :key="task.id">
<li>
<label>
<input type="checkbox" x-model="task.done">
<span :class="{ done: task.done }" x-text="task.title"></span>
</label>
</li>
</template>
</ul>
</div>Введите задачу и нажмите Enter — она появится в списке, а поле очистится. Чекбокс связан со свойством done: отметка зачёркивает задачу.
Другие поля
| Поле | Что попадает в свойство |
|---|---|
<input type="checkbox"> | true или false |
| Несколько чекбоксов с одним массивом | Массив значений value отмеченных |
<input type="radio"> | value выбранного |
<select> | value выбранного пункта |
<textarea> | Текст |
Пример с фильтром задач:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ filter: 'all' }">
<select x-model="filter">
<option value="all">Все</option>
<option value="active">Активные</option>
<option value="done">Выполненные</option>
</select>
<p x-text="'Фильтр: ' + filter"></p>
</div>Выберите другой пункт — строка под списком покажет его значение.
Модификаторы
| Модификатор | Что делает |
|---|---|
x-model.number | Превращает ввод в число |
x-model.lazy | Обновляет свойство при уходе из поля, а не на каждую клавишу |
x-model.debounce | Ждёт паузы в вводе, удобно для поиска |
Частая ошибка
Забыть .number у числового поля. Значение <input type="number"> всё равно приходит строкой, и сложение склеивает строки:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ hours: 2 }">
<input type="number" x-model="hours">
<p x-text="'Всего часов: ' + (hours + 1)"></p>
</div>Сначала выводится 3, но после ввода 5 появится «51». С x-model.number получится 6.