332 lines
8.8 KiB
Markdown

# 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
```vue
<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 object
- **`label`** (String, required) - Display label for the column header
- **`sortable`** (Boolean, default: `false`) - Enables sorting for this column
- **`filterable`** (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:
```javascript
{
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:
```javascript
{
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"`
```javascript
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
```vue
<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
```vue
<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
```vue
<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
```vue
<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 table
- `getTableFilters(tableName)` - Get current filters for a table
- `updateTableFilter(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
1. **Use unique `tableName`** for each table instance to avoid filter conflicts
2. **Define clear column labels** for better user experience
3. **Enable sorting and filtering** on searchable/comparable columns
4. **Use appropriate column types** (`status`, `button`) for better UX
5. **Handle `rowClick` events** for interactive functionality
6. **Consider data structure** - ensure `id` field exists for selection
7. **Test with various data sizes** to ensure performance
8. **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`)