QTable компонент таблиц

Компонент QTable в библиотеке Quasar предназначен для отображения табличных данных с поддержкой сортировки, фильтрации, пагинации, виртуализации и кастомизации отображения. Он объединяет в себе функциональность стандартной HTML-таблицы и мощный набор инструментов для работы с большими массивами данных.

QTable строится на декларативной модели: данные, структура колонок и поведение задаются через свойства (props), а визуализация может гибко настраиваться через слоты.


Базовая структура

Минимальная конфигурация QTable включает два ключевых параметра:

  • rows — массив данных
  • columns — описание колонок
const rows = [
  { name: 'John', age: 30, city: 'New York' },
  { name: 'Anna', age: 25, city: 'London' }
]

const columns = [
  {
    name: 'name',
    label: 'Имя',
    field: 'name',
    align: 'left',
    sortable: true
  },
  {
    name: 'age',
    label: 'Возраст',
    field: 'age',
    sortable: true
  },
  {
    name: 'city',
    label: 'Город',
    field: 'city'
  }
]
<q-table
  :rows="rows"
  :columns="columns"
  row-key="name"
/>

Описание колонок

Каждая колонка представляет объект с набором параметров:

  • name — уникальный идентификатор
  • label — заголовок
  • field — ключ или функция для получения значения
  • align — выравнивание (left, right, center)
  • sortable — возможность сортировки
  • format — функция форматирования

Пример с функцией:

{
  name: 'age',
  label: 'Возраст',
  field: row => row.age,
  format: val => `${val} лет`
}

Сортировка

QTable поддерживает сортировку из коробки. Для включения достаточно указать sortable: true.

Дополнительно можно задать пользовательскую логику:

{
  name: 'age',
  label: 'Возраст',
  field: 'age',
  sortable: true,
  sort: (a, b) => a - b
}

Начальное состояние сортировки задаётся через pagination:

const pagination = {
  sortBy: 'age',
  descending: false,
  page: 1,
  rowsPerPage: 10
}
<q-table
  :rows="rows"
  :columns="columns"
  :pagination.sync="pagination"
/>

Пагинация

QTable автоматически разбивает данные на страницы. Управление осуществляется через объект pagination.

Основные параметры:

  • page — текущая страница
  • rowsPerPage — количество строк
  • rowsNumber — общее количество (для серверной пагинации)

Отключение пагинации:

<q-table
  :rows="rows"
  :columns="columns"
  :pagination="{ rowsPerPage: 0 }"
/>

Фильтрация

Фильтрация выполняется через свойство filter:

<q-input v-model="filter" placeholder="Поиск..." />

<q-table
  :rows="rows"
  :columns="columns"
  :filter="filter"
/>

По умолчанию фильтр ищет по всем колонкам.

Для кастомной логики используется filter-method:

function customFilter(rows, terms) {
  return rows.filter(row =>
    row.name.toLowerCase().includes(terms.toLowerCase())
  )
}
<q-table
  :rows="rows"
  :columns="columns"
  :filter="filter"
  :filter-method="customFilter"
/>

Слоты и кастомизация

QTable активно использует слоты для переопределения отображения.

Слот ячейки

<template v-slot:body-cell-name="props">
  <q-td :props="props">
    <strong>{{ props.value }}</strong>
  </q-td>
</template>

Слот строки

<template v-slot:body="props">
  <q-tr :props="props">
    <q-td key="name">{{ props.row.name }}</q-td>
    <q-td key="age">{{ props.row.age }}</q-td>
  </q-tr>
</template>

Слот заголовка

<template v-slot:header="props">
  <q-tr :props="props">
    <q-th
      v-for="col in props.cols"
      :key="col.name"
    >
      {{ col.label.toUpperCase() }}
    </q-th>
  </q-tr>
</template>

Выбор строк

Поддерживается одиночный и множественный выбор:

<q-table
  :rows="rows"
  :columns="columns"
  selection="multiple"
  v-model:selected="selected"
/>

Доступные режимы:

  • single
  • multiple
  • none

Серверный режим

Для работы с API используется серверная пагинация, сортировка и фильтрация.

Ключевые параметры:

  • rowsNumber — общее количество строк
  • обработка события @request
<q-table
  :rows="rows"
  :columns="columns"
  :pagination="pagination"
  :loading="loading"
  @request="onRequest"
/>
function onRequest(props) {
  const { page, rowsPerPage, sortBy, descending } = props.pagination

  loading.value = true

  api.getData({ page, rowsPerPage, sortBy, descending })
    .then(response => {
      rows.value = response.data
      pagination.value.rowsNumber = response.total
    })
    .finally(() => {
      loading.value = false
    })
}

Виртуальный скролл

Для больших массивов данных используется виртуализация:

<q-table
  :rows="rows"
  :columns="columns"
  virtual-scroll
  :rows-per-page-options="[0]"
/>

Преимущества:

  • рендерятся только видимые строки
  • высокая производительность
  • уменьшение нагрузки на DOM

Расширенные возможности

Раскрывающиеся строки

<template v-slot:body="props">
  <q-tr :props="props">
    <q-td>{{ props.row.name }}</q-td>
  </q-tr>

  <q-tr v-if="props.expand">
    <q-td colspan="100%">
      Дополнительная информация
    </q-td>
  </q-tr>
</template>

Управление видимостью колонок

<q-table
  :visible-columns="visibleColumns"
/>
const visibleColumns = ['name', 'age']

Стилизация

QTable поддерживает стили через props:

  • dense — компактный режим
  • flat — без тени
  • bordered — с границами
  • square — без скруглений
<q-table
  dense
  bordered
  flat
/>

Интеграция с другими компонентами

Часто используется вместе с:

  • QInput — поиск
  • QSelect — фильтры
  • QPagination — кастомная пагинация
  • QBtn — действия

Пример панели управления:

<div class="row q-gutter-md">
  <q-input v-model="filter" label="Поиск" />
  <q-select v-model="selectedCity" :options="cities" />
</div>

Производительность и оптимизация

Рекомендации:

  • использовать row-key для уникальной идентификации
  • включать virtual-scroll при больших данных
  • минимизировать сложные вычисления в слотах
  • выносить форматирование в columns.format

Типичные сценарии применения

  • административные панели
  • системы управления данными (CRUD)
  • аналитические таблицы
  • отчётность
  • финансовые интерфейсы

QTable выступает как универсальный инструмент для работы с табличными структурами, обеспечивая баланс между простотой использования и глубокой кастомизацией.