Управление сложными формами

Petite-Vue — это легковесная и минималистичная библиотека, предназначенная для создания реактивных интерфейсов в веб-приложениях. Она предоставляет инструменты для работы с данными и интерфейсом, позволяя разработчикам организовывать поведение страниц в стиле Vue.js, но с меньшими требованиями к ресурсам. Одним из распространённых случаев использования является управление сложными формами, где нужно обновлять данные, валидировать их и взаимодействовать с сервером.

Основы работы с формами в Petite-Vue

В Petite-Vue можно легко управлять состоянием формы, связывая элементы с данными в модели. Это достигается с помощью директивы x-model, которая создает двустороннюю привязку данных. Когда пользователь вводит данные в форму, эти данные автоматически обновляют соответствующее поле модели.

Пример базовой формы:

<div x-data="{ name: '', email: '' }">
  <label>
    Имя:
    <input type="text" x-model="name" />
  </label>
  <label>
    Email:
    <input type="email" x-model="email" />
  </label>
  <button x-on:click="submitForm()">Отправить</button>
</div>

В этом примере каждый из элементов формы — это поле ввода, связанное с переменной в модели с помощью x-model. Когда пользователь вводит имя или email, соответствующие переменные обновляются. При нажатии на кнопку submitForm() можно будет обработать введённые данные.

Валидация данных формы

Одной из ключевых задач при работе с формами является валидация данных. В Petite-Vue можно легко реализовать простую валидацию с использованием реактивных переменных. Валидация может быть выполнена как в реальном времени, так и при отправке формы.

Пример проверки обязательных полей:

<div x-data="{ name: '', email: '', errors: [] }">
  <label>
    Имя:
    <input type="text" x-model="name" />
  </label>
  <label>
    Email:
    <input type="email" x-model="email" />
  </label>

  <button x-on:click="validateForm()">Отправить</button>

  <div x-show="errors.length > 0" style="color: red;">
    <ul>
      <template x-for="error in errors" :key="error">
        <li x-text="error"></li>
      </template>
    </ul>
  </div>
</div>

<script>
  function validateForm() {
    this.errors = [];
    if (!this.name) this.errors.push('Имя обязательно для заполнения');
    if (!this.email) this.errors.push('Email обязателен для заполнения');
    if (this.errors.length === 0) {
      // Отправка формы
    }
  }
</script>

Здесь создается переменная errors, которая хранит список сообщений об ошибках. Функция validateForm() проверяет, что поля формы не пустые, и если это так, добавляет соответствующие ошибки в список. Если ошибок нет, можно продолжить обработку данных, например, отправить их на сервер.

Асинхронная валидация

Иногда для валидации данных необходимо выполнить асинхронные операции, например, проверку уникальности email на сервере. Это можно сделать, например, с использованием JavaScript fetch API для отправки запросов на сервер.

Пример асинхронной валидации:

<div x-data="{ email: '', errors: [], isValidEmail: false }">
  <label>
    Email:
    <input type="email" x-model="email" />
  </label>

  <button x-on:click="validateEmail()">Проверить email</button>

  <div x-show="errors.length > 0" style="color: red;">
    <ul>
      <template x-for="error in errors" :key="error">
        <li x-text="error"></li>
      </template>
    </ul>
  </div>

  <div x-show="isValidEmail" style="color: green;">
    Email доступен.
  </div>
</div>

<script>
  function validateEmail() {
    this.errors = [];
    const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
    if (!emailPattern.test(this.email)) {
      this.errors.push('Неверный формат email');
      return;
    }

    fetch(`/check-email?email=${this.email}`)
      .then(response => response.json())
      .then(data => {
        if (data.exists) {
          this.errors.push('Этот email уже занят');
        } else {
          this.isValidEmail = true;
        }
      })
      .catch(() => {
        this.errors.push('Ошибка при проверке email');
      });
  }
</script>

Здесь при нажатии на кнопку выполняется проверка формата email, а затем происходит асинхронный запрос к серверу для проверки, существует ли уже такой email в базе данных. Если email доступен, выводится сообщение об этом, а если нет — ошибка.

Работа с динамическими формами

В некоторых случаях необходимо динамически изменять содержимое формы. Например, добавление новых полей в зависимости от предыдущего выбора пользователя. В Petite-Vue это можно легко реализовать с использованием реактивных данных и директивы x-for, которая позволяет повторно отображать элементы на основе массива данных.

Пример динамического добавления полей:

<div x-data="{ fields: [{ name: '' }] }">
  <template x-for="(field, index) in fields" :key="index">
    <label>
      Имя:
      <input type="text" x-model="field.name" />
    </label>
  </template>

  <button x-on:click="fields.push({ name: '' })">Добавить поле</button>
</div>

В этом примере создается форма с одним полем для ввода имени. Кнопка “Добавить поле” добавляет новый объект в массив fields, и для каждого объекта создается новое поле ввода. Каждый ввод связан с соответствующим объектом в массиве.

Обработка отправки формы

После того как форма валидирована и данные собраны, необходимо отправить их на сервер. Petite-Vue позволяет легко интегрировать работу с сервером через JavaScript, например, с помощью fetch.

Пример отправки формы:

<div x-data="{ name: '', email: '', isSubmitting: false }">
  <label>
    Имя:
    <input type="text" x-model="name" />
  </label>
  <label>
    Email:
    <input type="email" x-model="email" />
  </label>

  <button x-on:click="submitForm()">Отправить</button>

  <div x-show="isSubmitting">Отправка...</div>
</div>

<script>
  function submitForm() {
    this.isSubmitting = true;

    fetch('/submit-form', {
      method: 'POST',
      body: JSON.stringify({ name: this.name, email: this.email }),
      headers: {
        'Content-Type': 'application/json',
      },
    })
      .then(response => response.json())
      .then(data => {
        this.isSubmitting = false;
        alert('Форма успешно отправлена');
      })
      .catch(() => {
        this.isSubmitting = false;
        alert('Ошибка при отправке формы');
      });
  }
</script>

Здесь отправка данных осуществляется с помощью fetch, а перед этим устанавливается флаг isSubmitting, который сообщает пользователю, что процесс отправки формы начался. В случае успешной отправки или ошибки флаг сбрасывается, и выводится соответствующее сообщение.

Заключение

Petite-Vue предоставляет удобные инструменты для создания и управления сложными формами с динамическим обновлением данных, валидацией и отправкой на сервер. Реактивные данные, привязка с помощью x-model и управление состоянием позволяют эффективно работать с интерфейсами, не перегружая приложение лишними зависимостями.