A flexible data table for displaying structured datasets with support for sorting, sticky headers, column filters (text, select, multiselect), row hover/stripe styles, and a responsive mobile cards view.

When to Use ​

  • For displaying structured datasets with named columns that benefit from sorting and filtering
  • In dashboards, admin panels, or reporting views where users need to scan, sort, and narrow down rows
  • When mobile responsiveness is required — the mobile cards view adapts the layout for small screens

When Not to Use ​

  • For simple key–value information — use a <dl> or a card layout instead
  • For lists without columns — use QContainedList
  • When the dataset is empty by design — show an QEmptyState rather than an empty table

Component Anatomy ​

  • Header row — column labels; sortable columns show sort direction arrows
  • Data rows — one row per item; hover adds a highlight on mouse-over, striped alternates background colors
  • Sticky header — header remains visible during scroll when stickyHeader is enabled
  • Column filters — optional filter row below the header; each column can have a text, select, or multiselect filter
  • Mobile cards — collapses columns into stacked card items on small viewports

Fields and Items model ​

The following Vue reference will be used for any use case below:

Container Background — Uniform Rows ​

All rows share the same --q-body-container-bg surface. Use this when the table sits inside a card or panel with a different background, so each row reads as a clean slot.


Container Background — Striped Rows ​

Alternates between --q-body-container-bg (odd) and --q-body-quaternary-color (even). The quaternary tone is subtle enough to preserve readability at any font size while still clearly separating rows at a glance.


Row Hover ​

Keep column headers visible while scrolling through long tables. Perfect for maintaining context when working with large datasets.

Props ​

PropTypeDefaultDescription
stickyHeaderbooleanfalseEnable sticky table header that remains visible during scroll
stickyHeaderMaxHeightstring"600px"Maximum height of the scrollable table area

Column Filters ​

Enable column-level filtering to help users quickly find the data they need. Supports text search, single select, and multi-select filters.

Field Configuration ​

Configure filtering for each column using the QTableField interface:

Filter Types ​

  • text: Case-insensitive text search with 300ms debounce
  • select: Single selection dropdown with "All" option
  • multiselect: Multiple selection with checkboxes (AND logic)

Props ​

PropTypeDefaultDescription
columnFiltersbooleanfalseEnable column-level filtering
filtersQTableFilters{}v-model for current filter state

Mobile Cards View ​

Automatically switch to a card-based layout on mobile devices for better usability on smaller screens.

Field Configuration ​

Configure mobile display behavior using the QTableField interface:

Mobile Options ​

  • mobileLabel: Mark a field to display as the card title (defaults to first field)
  • mobilePriority: Control display order in cards (1 = highest priority)
  • mobileHidden: Hide field in mobile view
  • mobileSecondary: Mark field for secondary display styling

Props ​

PropTypeDefaultDescription
mobileCardsbooleanfalseEnable card view on mobile devices
mobileBreakpointBreakpointKey"isSmall"Breakpoint for switching to mobile view (< 768px)
mobileCardTitlestringundefinedField key to use as card title (overrides mobileLabel)

Combined Features ​

All features can be combined for a fully-featured responsive data table:

Props ​

PropTypeDefaultDescription
itemsTableItem[]requiredArray of data objects to display as table rows.
fieldsQTableField[]requiredColumn definitions (see QTableField type below).
hoverbooleanfalseHighlights rows on mouse-over.
stripedbooleanfalseAlternates background color on even/odd rows.
borderedbooleanfalseAdds borders to cells and the table outline.
smallbooleanfalseReduces cell padding for a more compact table.
stickyHeaderbooleanfalseKeeps the header row visible while scrolling.
stickyHeaderMaxHeightstring"600px"Maximum height of the scrollable area when stickyHeader is on.
columnFiltersbooleanfalseEnables per-column filter controls.
filtersQTableFilters{}Current filter state (use with v-model:filters).
mobileCardsbooleanfalseSwitches to a stacked card layout on small viewports.
mobileBreakpointBreakpointKey"isSmall"Viewport breakpoint below which the mobile cards view is applied.
mobileCardTitlestring—Field key to use as the card title, overriding mobileLabel.

QTableField Type ​

ts
type QTableField = {
  key: string;           // Property key in the item object
  label?: string;        // Column header text
  sortable?: boolean;    // Enables sort arrows on the column header
  formatter?: (args: { value: any; key: string; item: any }) => any; // Custom cell formatter
  filterable?: boolean;  // Enables a filter control for this column
  filterType?: "text" | "select" | "multiselect"; // Filter input type
  filterOptions?: { value: any; text: string }[]; // Options for select/multiselect filters
  mobileLabel?: boolean; // Use as card title in mobile cards view
  mobileSecondary?: boolean; // Secondary styling in mobile view
  mobilePriority?: number; // Display order in mobile cards (lower = higher priority)
  mobileHidden?: boolean; // Hide column in mobile cards view
};

Events ​

EventPayloadDescription
update:filtersQTableFiltersEmitted when a column filter value changes. Use with v-model:filters.
row-clickedTableItemEmitted when a data row is clicked, with the row's item data.
sort-changed{ key: string; order: "asc" | "desc" }Emitted when the user clicks a sortable column header.

Accessibility ​

  • Column headers use <th scope="col"> elements for proper screen reader association
  • Sortable columns communicate their state via aria-sort ("ascending" or "descending")
  • Row hover and striped styles are visual only; do not rely on them to convey row state
  • When using column filters, ensure filter inputs have visible labels or aria-label attributes
  • On mobile cards view, ensure the card layout maintains a logical reading order for screen readers