Редактируемые ячейки

Редактируемые ячейки в Vuetify реализуются в основном через компонент v-data-table с использованием слотов и встроенных компонентов ввода, таких как v-text-field, v-select, v-checkbox и других. Возможность редактирования ячеек делает таблицы интерактивными и позволяет управлять данными без необходимости открывать отдельные формы.


Использование слотов для редактирования

Ключевой механизм для редактирования ячеек — это слоты item.<имя_поля>. Они позволяют заменить стандартное отображение ячейки на кастомный компонент ввода.

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

<v-data-table
  :headers="headers"
  :items="items"
  item-key="id"
>
  <template v-slot:item.name="{ item }">
    <v-text-field
      v-model="item.name"
      solo
      hide-details
      dense
    ></v-text-field>
  </template>
</v-data-table>

Пояснения:

  • v-model связывает значение ячейки с объектом данных, что обеспечивает мгновенное обновление.
  • solo убирает обрамление поля ввода, делая интерфейс более компактным.
  • hide-details скрывает подсказки и ошибки, упрощая внешний вид.
  • dense уменьшает высоту поля для соответствия стилю таблицы.

Редактирование числовых и булевых значений

Для числовых данных можно использовать v-text-field с типом number:

<template v-slot:item.age="{ item }">
  <v-text-field
    v-model.number="item.age"
    type="number"
    solo
    dense
    hide-details
  ></v-text-field>
</template>

Для булевых значений удобно использовать v-checkbox:

<template v-slot:item.active="{ item }">
  <v-checkbox
    v-model="item.active"
    hide-details
    dense
  ></v-checkbox>
</template>

Ключевой момент: использование .number в v-model позволяет автоматически преобразовывать ввод в числовой тип, предотвращая ошибки при математических операциях.


Редактируемые селекты и комбинированные поля

Для ячеек, где возможен выбор из нескольких вариантов, применяется v-select:

<template v-slot:item.role="{ item }">
  <v-select
    v-model="item.role"
    :items="roles"
    solo
    hide-details
    dense
  ></v-select>
</template>
  • :items задаёт массив доступных опций.
  • v-model связывает выбранное значение с объектом данных.

Для сложных интерфейсов можно комбинировать несколько компонентов, например, v-menu + v-date-picker для редактирования дат прямо в ячейке:

<template v-slot:item.dueDate="{ item }">
  <v-menu
    v-model="item.menu"
    :close-on-content-click="false"
    transition="scale-transition"
    offset-y
    min-width="auto"
  >
    <template #activator="{ on, attrs }">
      <v-text-field
        v-model="item.dueDate"
        readonly
        v-bind="attrs"
        v-on="on"
        dense
        hide-details
        solo
      ></v-text-field>
    </template>
    <v-date-picker v-model="item.dueDate" @input="item.menu = false"></v-date-picker>
  </v-menu>
</template>

Особенности реализации:

  • Использование v-menu позволяет отображать календарь только при взаимодействии с ячейкой.
  • Связь между v-model текстового поля и v-date-picker обеспечивает синхронизацию даты.
  • Закрытие меню после выбора даты предотвращает лишние клики.

Валидация и обработка изменений

Редактируемые ячейки часто требуют проверки данных. Vuetify поддерживает встроенную валидацию через rules:

<v-text-field
  v-model="item.email"
  :rules="[v => /.+@.+\..+/.test(v) || 'Неверный email']"
  solo
  dense
  hide-details
></v-text-field>

Особенности:

  • Массив rules содержит функции или строки для проверки данных.
  • Возврат строки отображает сообщение об ошибке, возврат true означает успешную проверку.

Для массовой обработки изменений можно отслеживать события @input или использовать реактивные наблюдения Vue:

watch: {
  items: {
    handler(newItems) {
      console.log('Данные таблицы обновлены', newItems);
    },
    deep: true
  }
}

Редактирование с сохранением на сервер

Для синхронизации данных с сервером используется метод @blur или отдельная кнопка сохранения. Пример с отправкой через axios:

<v-text-field
  v-model="item.name"
  @blur="saveItem(item)"
  solo
  dense
  hide-details
></v-text-field>

methods: {
  async saveItem(item) {
    try {
      await axios.put(`/api/items/${item.id}`, item)
      console.log('Сохранено на сервере', item)
    } catch (error) {
      console.error('Ошибка сохранения', error)
    }
  }
}

Преимущества такого подхода:

  • Мгновенное локальное редактирование.
  • Минимизация количества запросов к серверу (сохранение только по событию blur).
  • Возможность централизованной обработки ошибок.

Стилизация и UX редактируемых ячеек

  • Использование dense и solo делает редактируемые ячейки компактными.
  • hide-details убирает визуальный шум.
  • Можно выделять редактируемые ячейки через class="editable-cell" с подсветкой при фокусе.
  • Для больших таблиц удобно использовать инлайновую подсказку через v-tooltip или hint свойства.

Оптимизация для больших данных

  • Использовать v-virtual-scroll или включать virtual свойство у v-data-table для оптимизации рендеринга.
  • Разделять редактируемые и не редактируемые столбцы для снижения нагрузки.
  • Обновлять только измененные строки, а не весь массив данных.

Редактируемые ячейки в Vuetify — мощный инструмент для создания динамических интерфейсов. Комбинирование слотов, реактивного v-model, встроенных компонентов ввода и правил валидации позволяет строить гибкие, интерактивные таблицы с поддержкой сложных пользовательских сценариев.