This component is experimental. The API may change in future versions.
import { MtDataTable } from '@/components/table-and-list/mt-data-table/mt-data-table.vue';
import type { ColumnDefinition } from '@/components/table-and-list/mt-data-table/mt-data-table.vue';
Column Definition Types
interface BaseColumnDefinition {
label: string; // Column header label
property: string; // Data property key
position: number; // Initial position (use 100-step increments)
sortable?: boolean; // Enable sorting (default: true)
width?: number; // Column width in pixels
allowResize?: boolean; // Allow user resizing
cellWrap?: 'nowrap' | 'normal'; // Text wrapping behavior
visible?: boolean; // Initial visibility
}
type ColumnDefinition =
| TextColumnDefinition
| NumberColumnDefinition
| BadgeColumnDefinition
| PriceColumnDefinition;
Main Props
Data & Columns
dataSource
Array<{ id: string; [key: string]: unknown }>
required
The data to display in the table. Each item must have a unique id property.
columns
ColumnDefinition[]
required
Column definitions specifying how to render each column. Each column must have label, property, renderer, and position.
columnChanges
Record<string, ColumnChanges>
default:"{}"
Object storing user customizations (width, position, visibility) for persisting table state.
Display
Table title displayed in the card header.
Table subtitle displayed below the title.
caption
string
default:"Data table"
Accessibility caption for screen readers.
layout
'default' | 'full'
default:"default"
Table layout mode.
Current page number (1-indexed).
Number of items per page.
Total number of items across all pages.
Available items-per-page options.
Sorting
Property name of the currently sorted column.
sortDirection
'ASC' | 'DESC'
default:"ASC"
Current sort direction.
Search & Filters
Disable the search input.
Current search query value.
Available filter definitions.
Currently applied filters.
Number of results matching current filters.
Features
Show loading skeleton state.
Show reload button in footer.
Enable row selection checkboxes.
Array of selected row IDs.
Array of row IDs that cannot be selected.
Show row numbers in first column.
Enable alternating row background colors.
Highlight cell outlines on hover.
Actions
Hide table settings menu.
Enable bulk edit when rows are selected.
Enable bulk delete when rows are selected.
Additional custom bulk actions.
Additional context menu items for each row.
Emitted when reload button is clicked.
Emitted when items per page changes.
Emitted when page changes.
Emitted when search input changes.
Emitted when sort column or direction changes.
Emitted when row edit is triggered.
Emitted when delete action is triggered for a row.
Emitted when a single row selection changes.
multiple-selection-change
Emitted when select all is toggled.
Emitted when bulk edit action is triggered.
Emitted when bulk delete action is triggered.
Emitted when filters change.
Emitted when custom context menu item is clicked.
Usage Examples
Basic Table
<template>
<mt-data-table
:data-source="products"
:columns="columns"
:current-page="currentPage"
:pagination-limit="limit"
:pagination-total-items="totalItems"
title="Products"
@pagination-current-page-change="currentPage = $event"
@pagination-limit-change="limit = $event"
/>
</template>
<script setup>
import { ref } from 'vue';
const products = ref([
{ id: '1', name: 'Product A', price: 29.99, stock: 150 },
{ id: '2', name: 'Product B', price: 49.99, stock: 75 },
{ id: '3', name: 'Product C', price: 19.99, stock: 200 },
]);
const columns = [
{
label: 'Name',
property: 'name',
renderer: 'text',
position: 100,
sortable: true
},
{
label: 'Price',
property: 'price',
renderer: 'price',
position: 200
},
{
label: 'Stock',
property: 'stock',
renderer: 'number',
position: 300
}
];
const currentPage = ref(1);
const limit = ref(10);
const totalItems = ref(products.value.length);
</script>
Table with Search and Sorting
<template>
<mt-data-table
:data-source="filteredData"
:columns="columns"
:current-page="page"
:pagination-limit="limit"
:pagination-total-items="total"
:search-value="searchQuery"
:sort-by="sortBy"
:sort-direction="sortDirection"
@search-value-change="handleSearch"
@sort-change="handleSort"
/>
</template>
<script setup>
import { ref, computed } from 'vue';
const searchQuery = ref('');
const sortBy = ref('name');
const sortDirection = ref('ASC');
const handleSearch = (query) => {
searchQuery.value = query;
// Implement search logic
};
const handleSort = ({ sortBy: column, sortDirection: direction }) => {
sortBy.value = column;
sortDirection.value = direction;
// Implement sorting logic
};
</script>
Table with Row Selection and Bulk Actions
<template>
<mt-data-table
:data-source="items"
:columns="columns"
:allow-row-selection="true"
:selected-rows="selectedRows"
:allow-bulk-edit="true"
:allow-bulk-delete="true"
@selection-change="handleSelectionChange"
@bulk-edit="handleBulkEdit"
@bulk-delete="handleBulkDelete"
/>
</template>
<script setup>
const selectedRows = ref([]);
const handleSelectionChange = (rowId, isSelected) => {
if (isSelected) {
selectedRows.value.push(rowId);
} else {
selectedRows.value = selectedRows.value.filter(id => id !== rowId);
}
};
const handleBulkEdit = () => {
console.log('Bulk edit:', selectedRows.value);
};
const handleBulkDelete = () => {
console.log('Bulk delete:', selectedRows.value);
};
</script>
Table with Custom Columns
<template>
<mt-data-table :data-source="data" :columns="columns">
<template #column-status="{ data }">
<mt-badge :variant="getStatusVariant(data.status)">
{{ data.status }}
</mt-badge>
</template>
<template #column-actions="{ data }">
<mt-button size="small" @click="customAction(data)">
Custom Action
</mt-button>
</template>
</mt-data-table>
</template>
Column Renderers
The data table supports these built-in renderers:
text: Standard text display
number: Formatted number display
badge: Badge component for status/labels
price: Currency formatting
See individual renderer documentation for specific properties.