8.8 KiB
8.8 KiB
DataTable Component Documentation
Overview
A feature-rich data table component built with PrimeVue's DataTable. This component provides advanced functionality including pagination, sorting, filtering, row selection, and customizable column types with persistent filter state management.
Basic Usage
<template>
<DataTable
:columns="tableColumns"
:data="tableData"
table-name="my-table"
@row-click="handleRowClick"
/>
</template>
<script setup>
import { ref } from 'vue'
import DataTable from './components/common/DataTable.vue'
const tableColumns = ref([
{
fieldName: 'name',
label: 'Name',
sortable: true,
filterable: true
},
{
fieldName: 'status',
label: 'Status',
type: 'status',
sortable: true,
filterable: true
}
])
const tableData = ref([
{ id: 1, name: 'John Doe', status: 'completed' },
{ id: 2, name: 'Jane Smith', status: 'in progress' }
])
const handleRowClick = (event) => {
console.log('Row clicked:', event.data)
}
</script>
Props
columns (Array) - Required
- Description: Array of column configuration objects that define the table structure
- Type:
Array<Object> - Required:
true
data (Array) - Required
- Description: Array of data objects to display in the table
- Type:
Array<Object> - Required:
true
tableName (String) - Required
- Description: Unique identifier for the table, used for persistent filter state management
- Type:
String - Required:
true
filters (Object)
- Description: Initial filter configuration object
- Type:
Object - Default:
{ global: { value: null, matchMode: FilterMatchMode.CONTAINS } }
Column Configuration
Each column object in the columns array supports the following properties:
Basic Properties
fieldName(String, required) - The field name in the data objectlabel(String, required) - Display label for the column headersortable(Boolean, default:false) - Enables sorting for this columnfilterable(Boolean, default:false) - Enables row-level filtering for this column
Column Types
type(String) - Defines special rendering behavior for the column
Available Types:
'status' Type
Renders values as colored tags/badges:
{
fieldName: 'status',
label: 'Status',
type: 'status',
sortable: true,
filterable: true
}
Status Colors:
'completed'→ Success (green)'in progress'→ Warning (yellow/orange)'not started'→ Danger (red)- Other values → Info (blue)
'button' Type
Renders values as clickable buttons:
{
fieldName: 'action',
label: 'Action',
type: 'button'
}
Events
rowClick
- Description: Emitted when a button-type column is clicked
- Payload: PrimeVue slot properties object containing row data
- Usage:
@row-click="handleRowClick"
const handleRowClick = (slotProps) => {
console.log('Clicked row data:', slotProps.data)
console.log('Row index:', slotProps.index)
}
Features
Pagination
- Rows per page options: 5, 10, 20, 50
- Default rows per page: 10
- Built-in pagination controls
Sorting
- Multiple column sorting support
- Removable sort - click to remove sort from a column
- Sort indicators in column headers
Filtering
- Row-level filtering for filterable columns
- Text-based search with real-time filtering
- Persistent filter state across component re-renders
- Global search capability
Selection
- Multiple row selection with checkboxes
- Meta key selection (Ctrl/Cmd + click for individual selection)
- Unique row identification using
dataKey="id"
Scrolling
- Vertical scrolling with fixed height (70vh)
- Horizontal scrolling for wide tables
- Fixed headers during scroll
State Management
- Persistent filters using Pinia store (
useFiltersStore) - Automatic filter initialization on component mount
- Cross-component filter synchronization
Usage Examples
Basic Table
<script setup>
const columns = [
{ fieldName: 'id', label: 'ID', sortable: true },
{ fieldName: 'name', label: 'Name', sortable: true, filterable: true },
{ fieldName: 'email', label: 'Email', filterable: true }
]
const data = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
]
</script>
<template>
<DataTable
:columns="columns"
:data="data"
table-name="users-table"
/>
</template>
Status Table
<script setup>
const columns = [
{ fieldName: 'task', label: 'Task', sortable: true, filterable: true },
{ fieldName: 'status', label: 'Status', type: 'status', sortable: true, filterable: true },
{ fieldName: 'assignee', label: 'Assignee', filterable: true }
]
const data = [
{ id: 1, task: 'Setup project', status: 'completed', assignee: 'John' },
{ id: 2, task: 'Write tests', status: 'in progress', assignee: 'Jane' },
{ id: 3, task: 'Deploy app', status: 'not started', assignee: 'Bob' }
]
</script>
<template>
<DataTable
:columns="columns"
:data="data"
table-name="tasks-table"
/>
</template>
Interactive Table with Buttons
<script setup>
const columns = [
{ fieldName: 'name', label: 'Name', sortable: true, filterable: true },
{ fieldName: 'status', label: 'Status', type: 'status', sortable: true },
{ fieldName: 'action', label: 'Action', type: 'button' }
]
const data = [
{ id: 1, name: 'Project A', status: 'completed', action: 'View Details' },
{ id: 2, name: 'Project B', status: 'in progress', action: 'Edit' }
]
const handleRowClick = (slotProps) => {
const { data, index } = slotProps
console.log(`Action clicked for ${data.name} at row ${index}`)
// Handle the action (navigate, open modal, etc.)
}
</script>
<template>
<DataTable
:columns="columns"
:data="data"
table-name="projects-table"
@row-click="handleRowClick"
/>
</template>
Custom Filters
<script setup>
import { FilterMatchMode } from '@primevue/core'
const customFilters = {
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
name: { value: 'John', matchMode: FilterMatchMode.STARTS_WITH }
}
</script>
<template>
<DataTable
:columns="columns"
:data="data"
:filters="customFilters"
table-name="filtered-table"
/>
</template>
Store Integration
The component integrates with a Pinia store (useFiltersStore) for persistent filter state:
Store Methods Used
initializeTableFilters(tableName, columns)- Initialize filters for a tablegetTableFilters(tableName)- Get current filters for a tableupdateTableFilter(tableName, fieldName, value, matchMode)- Update a specific filter
Filter Persistence
- Filters are automatically saved when changed
- Filters persist across component re-mounts
- Each table maintains separate filter state based on
tableName
Styling
The component uses PrimeVue's default DataTable styling with:
- Scrollable layout with fixed 70vh height
- Responsive design that adapts to container width
- Consistent spacing and typography
- Accessible color schemes for status badges
Performance Considerations
Large Datasets
- Virtual scrolling is not implemented - consider for datasets > 1000 rows
- Client-side pagination may impact performance with very large datasets
- Debounced filtering helps with real-time search performance
Memory Management
- Filter state persistence may accumulate over time
- Consider implementing filter cleanup for unused tables
- Component re-rendering is optimized through computed properties
Best Practices
- Use unique
tableNamefor each table instance to avoid filter conflicts - Define clear column labels for better user experience
- Enable sorting and filtering on searchable/comparable columns
- Use appropriate column types (
status,button) for better UX - Handle
rowClickevents for interactive functionality - Consider data structure - ensure
idfield exists for selection - Test with various data sizes to ensure performance
- Use consistent status values for proper badge coloring
Accessibility
The component includes:
- Keyboard navigation support via PrimeVue
- Screen reader compatibility with proper ARIA labels
- High contrast status badges for visibility
- Focus management for interactive elements
- Semantic HTML structure for assistive technologies
Browser Support
Compatible with all modern browsers that support:
- Vue 3 Composition API
- ES6+ features
- CSS Grid and Flexbox
- PrimeVue components
Dependencies
- Vue 3 with Composition API
- PrimeVue DataTable, Column, Tag, Button, InputText components
- @primevue/core for FilterMatchMode
- Pinia store for state management (
useFiltersStore)