Skip to content

BaseDataTable

A responsive data table component built on native HTML <table>. Supports single/multiple row selection, expandable rows, loading states, striped rows, and custom cell rendering via named slots.

Basic Usage

Demo
NameRoleStatusJoined
Alice JohnsonDesignerActive2023-01-15
Bob SmithEngineerActive2022-07-20
Carol WilliamsProductAway2023-03-08
David BrownEngineerActive2021-11-30
Eva MartinezDesignerInactive2024-01-01

Multiple Selection

Multiple Selection
NameRoleStatusJoined
Alice JohnsonDesignerActive2023-01-15
Bob SmithEngineerActive2022-07-20
Carol WilliamsProductAway2023-03-08
David BrownEngineerActive2021-11-30
Eva MartinezDesignerInactive2024-01-01

Selected: None

Striped Rows + Loading

Striped + Loading
NameRoleStatusJoined

Custom Cell Rendering

Use slotName on a column to render custom content in that cell:

vue
<BaseDataTable :items="items" :columns="columns">
  <template #status="{ data }">
    <span
      class="badge"
      :class="data.status === 'Active' ? 'badge-green' : 'badge-gray'"
    >
      {{ data.status }}
    </span>
  </template>
</BaseDataTable>

Define slotName on the column definition:

ts
const columns = [
  { field: 'name', header: 'Name' },
  { field: 'status', header: 'Status', slotName: 'status' },
]

Props

Props
PropTypeDefaultDescription
itemsRecord<string, unknown>[][]Array of row data objects. Each row should have a unique id field.
columnsColumnDef[][]Column definitions. See ColumnDef interface below.
loadingbooleanfalseShows a centered spinner and hides row data.
rowsnumber10Number of rows per page (for pagination, not yet implemented natively).
selectionMode'single' | 'multiple' | undefinedundefinedEnables row selection. 'multiple' shows checkboxes, 'single' shows radio buttons.
selectedItemsRecord<string, unknown>[][]Currently selected rows. Use alongside @selection-change.
stripedRowsbooleanfalseAlternates row background colors for easier scanning.
emptyMessagestring'No data available'Message shown when items array is empty and not searching.
searchEmptyMessagestring'No results found'Message shown when items is empty and isSearching is true.
isSearchingbooleanfalseWhen true, uses searchEmptyMessage for the empty state.
enableRowDblClickbooleanfalseEnables double-click events on rows.
expanderCondition(row) => booleanundefinedFunction that returns whether a row should show the expander button.

ColumnDef

ts
interface ColumnDef {
  field: string          // Property name from the row object
  header: string         // Column header text
  slotName?: string      // Named slot for custom cell rendering
  style?: string | Record<string, string>  // CSS styles for the column
  sortable?: boolean     // Reserved (not implemented)
  frozen?: boolean       // Reserved (not implemented)
}

Emits

Emits
EventPayloadDescription
row-clickunknownEmitted 300ms after a single click on a row (debounced to avoid conflict with dblclick).
row-dblclickunknownEmitted on double-click. Requires enableRowDblClick to be true.
selection-changeunknownEmitted when row selection changes. Returns the full updated selection array.

Slots

Slots
SlotScopeDescription
[slotName]{ data: row }Custom cell content. Name must match slotName in the column definition.
expansion{ data: row }Expandable row content. Presence of this slot automatically adds an expander column.

Built with VitePress