Формы — это основа почти любого веб-приложения. От простых текстовых полей до сложных форм с валидацией и отправкой данных на сервер. Vue.js, благодаря своей реактивности и удобным инструментам, делает работу с формами максимально простой и удобной. В этой статье мы подробно разберём, как работать с формами в Vue 3, используя Composition API.
Двусторонняя привязка данных: v-model
Когда речь заходит о формах, первое, что приходит на ум — это привязка данных к элементам формы. Vue.js предлагает удобную директиву v-model, которая позволяет связать значение поля с переменной в вашем компоненте. Давайте начнём с самого простого примера — текстового поля:
<template>
<div>
<input v-model="name" placeholder="Введите своё имя">
<p>Привет, {{ name }}!</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const name = ref('');
</script>
Здесь с помощью v-model мы связываем переменную name с полем ввода. Любое изменение в поле сразу же отображается в p-теге благодаря реактивности Vue. Двусторонняя привязка данных работает «из коробки» — изменение значения в форме автоматически обновляет переменную, и наоборот.
Работа с различными типами полей
Vue.js отлично поддерживает работу с разными типами форм, будь то текстовые поля, чекбоксы, радиокнопки или выпадающие списки. Рассмотрим каждый тип:
Чекбоксы
Чекбоксы могут быть связаны с булевой переменной:
<template>
<div>
<input type="checkbox" v-model="isChecked">
<p>Чекбокс {{ isChecked ? 'отмечен' : 'не отмечен' }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isChecked = ref(false);
</script>
Здесь isChecked будет обновляться в зависимости от состояния чекбокса.
Радиокнопки
Радиокнопки позволяют выбрать один вариант из нескольких. В этом случае v-model привязывается к одному значению:
<template>
<div>
<input type="radio" v-model="selectedOption" value="option1"> Опция 1
<input type="radio" v-model="selectedOption" value="option2"> Опция 2
<p>Вы выбрали: {{ selectedOption }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const selectedOption = ref('');
</script>
Теперь переменная selectedOption будет хранить значение выбранной радиокнопки.
Выпадающие списки
Выпадающие списки (select) также поддерживают v-model, и это позволяет удобно управлять выбором:
<template>
<div>
<select v-model="selectedFruit">
<option value="apple">Яблоко</option>
<option value="banana">Банан</option>
<option value="cherry">Вишня</option>
</select>
<p>Ваш выбор: {{ selectedFruit }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const selectedFruit = ref('');
</script>
Теперь selectedFruit будет содержать значение выбранного элемента списка.
Валидация данных
Привязка данных — это хорошо, но реальный мир требует валидации. Вы же не хотите, чтобы пользователи отправляли формы с пустыми полями или некорректными данными. Vue.js предлагает несколько способов валидировать данные в форме. Один из самых простых способов — использование вычисляемых свойств и обычной логики в компонентах.
Давайте проверим, что пользователь ввёл имя длиной не менее 3 символов:
<template>
<div>
<input v-model="name" placeholder="Введите своё имя">
<p v-if="nameError">{{ nameError }}</p>
<button :disabled="!isFormValid">Отправить</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const name = ref('');
const nameError = computed(() => {
if (name.value.length < 3) {
return 'Имя должно быть не менее 3 символов';
}
return '';
});
const isFormValid = computed(() => {
return !nameError.value;
});
</script>
В этом примере мы используем вычисляемое свойство nameError для проверки длины строки. Если условие не выполнено, выводим ошибку. Кнопка отправки формы становится активной только при выполнении всех условий.
Множественные поля и динамические формы
Что, если у вас есть динамическая форма, количество полей в которой зависит от действий пользователя? Vue отлично справляется и с этим.
Представим, что мы хотим добавить несколько полей для ввода имён:
<template>
<div>
<div v-for="(name, index) in names" :key="index">
<input v-model="name.value" placeholder="Введите имя">
<button @click="removeName(index)">Удалить</button>
</div>
<button @click="addName">Добавить имя</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const names = ref([{ value: '' }]);
const addName = () => {
names.value.push({ value: '' });
};
const removeName = (index) => {
names.value.splice(index, 1);
};
</script>
Этот пример позволяет пользователю добавлять и удалять поля ввода динамически. Каждый элемент списка names — это отдельный объект, что делает работу с реактивностью Vue ещё более гибкой.
Работа с формами и Vuex/Pinia
Если ваше приложение становится сложнее, и вам нужно управлять состоянием форм глобально, например, при работе с несколькими страницами или компонентами, вам может потребоваться интеграция с хранилищем данных, таким как Pinia или Vuex.
Рассмотрим пример с использованием Pinia для сохранения данных формы:
<template>
<div>
<input v-model="name" placeholder="Введите своё имя">
<p>Привет, {{ name }}!</p>
<button @click="submitForm">Сохранить</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useFormStore } from './stores/formStore';
const name = ref('');
const formStore = useFormStore();
const submitForm = () => {
formStore.saveName(name.value);
};
</script>
Хранилище formStore может выглядеть так:
import { defineStore } from 'pinia';
export const useFormStore = defineStore('form', {
state: () => ({
name: ''
}),
actions: {
saveName(newName) {
this.name = newName;
}
}
});
Теперь данные формы сохраняются в хранилище и могут быть использованы в других частях приложения.
Итоги
Работа с формами в Vue 3 — это интуитивный и гибкий процесс. С помощью v-model можно легко связать данные с полями ввода, а встроенные модификаторы и вычисляемые свойства позволяют без труда обрабатывать валидацию и другие аспекты взаимодействия. Благодаря реактивности и удобным инструментам, создание даже сложных форм с динамическими полями становится гораздо проще.
Мы рассмотрели, как работать с различными типами полей, как проверять данные перед отправкой и как сохранять данные в глобальном хранилище. Это — лишь малая часть того, что можно сделать с Vue 3, но она охватывает самые важные аспекты работы с формами в реальных приложениях.