0
# Data Display
1
2
Components for displaying and managing data in various formats including tables, lists, and hierarchical structures.
3
4
## Capabilities
5
6
### VDataTable
7
8
Feature-rich data table component with sorting, filtering, pagination, and selection capabilities.
9
10
```typescript { .api }
11
/**
12
* Advanced data table with server-side and client-side data management
13
*/
14
const VDataTable: Component;
15
16
interface DataTableProps {
17
/** Array of data items to display */
18
items?: any[];
19
/** Array of header configuration objects */
20
headers?: DataTableHeader[];
21
/** Current page number (1-based) */
22
page?: number;
23
/** Number of items per page */
24
itemsPerPage?: number;
25
/** Total number of items for server-side pagination */
26
itemsLength?: number;
27
/** Array of sort configuration objects */
28
sortBy?: DataTableSortItem[];
29
/** Whether multiple columns can be sorted */
30
multiSort?: boolean;
31
/** Item selection strategy */
32
selectStrategy?: SelectStrategy;
33
/** Array of selected item keys */
34
modelValue?: any[];
35
/** Search query string for filtering */
36
search?: string;
37
/** Custom filter function */
38
customFilter?: FilterFunction;
39
/** Whether to show select checkboxes */
40
showSelect?: boolean;
41
/** Whether to show expand icons */
42
showExpand?: boolean;
43
/** Item value key for identification */
44
itemValue?: string | ((item: any) => any);
45
/** Item title key for display */
46
itemTitle?: string | ((item: any) => any);
47
/** Return object format for items */
48
returnObject?: boolean;
49
/** Table density setting */
50
density?: 'default' | 'comfortable' | 'compact';
51
/** Fixed header while scrolling */
52
fixedHeader?: boolean;
53
/** Fixed footer while scrolling */
54
fixedFooter?: boolean;
55
/** Table height for virtual scrolling */
56
height?: string | number;
57
/** Whether table content is loading */
58
loading?: boolean;
59
/** Loading text to display */
60
loadingText?: string;
61
/** Text when no data available */
62
noDataText?: string;
63
/** Hide default footer */
64
hideDefaultFooter?: boolean;
65
/** Hide default header */
66
hideDefaultHeader?: boolean;
67
/** Disable sorting functionality */
68
disableSort?: boolean;
69
/** Make rows hoverable */
70
hover?: boolean;
71
/** Custom row props function */
72
rowProps?: DataTableRowPropsFunction;
73
/** Custom cell props function */
74
cellProps?: DataTableCellPropsFunction;
75
}
76
77
interface DataTableHeader {
78
/** Unique key for the column */
79
key: string;
80
/** Column title text */
81
title?: string;
82
/** Value path for nested objects */
83
value?: string;
84
/** Column span count */
85
colspan?: number;
86
/** Row span count */
87
rowspan?: number;
88
/** Whether column is sortable */
89
sortable?: boolean;
90
/** Custom sort function */
91
sort?: DataTableCompareFunction;
92
/** Text alignment */
93
align?: 'start' | 'center' | 'end';
94
/** Column width */
95
width?: string | number;
96
/** Minimum column width */
97
minWidth?: string | number;
98
/** Maximum column width */
99
maxWidth?: string | number;
100
/** Whether column is fixed */
101
fixed?: boolean;
102
/** Filter function for this column */
103
filter?: FilterFunction;
104
}
105
106
interface DataTableSortItem {
107
/** Column key to sort by */
108
key: string;
109
/** Sort order */
110
order?: 'asc' | 'desc';
111
}
112
113
type DataTableCompareFunction<T = any> = (a: T, b: T) => number;
114
type DataTableRowPropsFunction = (data: { item: any; index: number }) => Record<string, any>;
115
type DataTableCellPropsFunction = (data: { item: any; column: DataTableHeader; index: number }) => Record<string, any>;
116
117
// Events
118
interface DataTableEvents {
119
'update:modelValue': (value: any[]) => void;
120
'update:page': (page: number) => void;
121
'update:itemsPerPage': (itemsPerPage: number) => void;
122
'update:sortBy': (sortBy: DataTableSortItem[]) => void;
123
'update:expanded': (expanded: any[]) => void;
124
'click:row': (event: Event, data: { item: any; index: number }) => void;
125
'contextmenu:row': (event: Event, data: { item: any; index: number }) => void;
126
}
127
```
128
129
**Usage Examples:**
130
131
```vue
132
<template>
133
<!-- Basic data table -->
134
<v-data-table
135
:items="items"
136
:headers="headers"
137
item-value="id"
138
/>
139
140
<!-- With selection and pagination -->
141
<v-data-table
142
v-model="selected"
143
:items="items"
144
:headers="headers"
145
:items-per-page="10"
146
show-select
147
item-value="id"
148
@click:row="handleRowClick"
149
/>
150
151
<!-- Server-side data table -->
152
<v-data-table
153
:items="serverItems"
154
:headers="headers"
155
:items-length="totalItems"
156
:loading="loading"
157
@update:page="loadPage"
158
@update:items-per-page="updateItemsPerPage"
159
@update:sort-by="updateSort"
160
/>
161
</template>
162
163
<script setup>
164
const headers = [
165
{ title: 'Name', key: 'name', sortable: true },
166
{ title: 'Email', key: 'email', sortable: true },
167
{ title: 'Role', key: 'role', sortable: false },
168
{ title: 'Actions', key: 'actions', sortable: false },
169
];
170
171
const items = ref([
172
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
173
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
174
]);
175
176
const selected = ref([]);
177
</script>
178
```
179
180
### VDataIterator
181
182
Flexible data display component with customizable item templates and built-in pagination.
183
184
```typescript { .api }
185
/**
186
* Flexible data iterator with custom item templates
187
*/
188
const VDataIterator: Component;
189
190
interface DataIteratorProps {
191
/** Array of data items */
192
items?: any[];
193
/** Current page number */
194
page?: number;
195
/** Items per page */
196
itemsPerPage?: number;
197
/** Total items count for server-side */
198
itemsLength?: number;
199
/** Sort configuration */
200
sortBy?: DataTableSortItem[];
201
/** Search query */
202
search?: string;
203
/** Custom filter function */
204
customFilter?: FilterFunction;
205
/** Item value key */
206
itemValue?: string | ((item: any) => any);
207
/** Return object format */
208
returnObject?: boolean;
209
/** Loading state */
210
loading?: boolean;
211
/** No data text */
212
noDataText?: string;
213
}
214
215
// Events
216
interface DataIteratorEvents {
217
'update:page': (page: number) => void;
218
'update:itemsPerPage': (itemsPerPage: number) => void;
219
'update:sortBy': (sortBy: DataTableSortItem[]) => void;
220
}
221
```
222
223
**Usage Examples:**
224
225
```vue
226
<template>
227
<v-data-iterator
228
:items="items"
229
:items-per-page="6"
230
>
231
<template #default="{ items }">
232
<v-row>
233
<v-col
234
v-for="item in items"
235
:key="item.id"
236
cols="12"
237
sm="6"
238
md="4"
239
>
240
<v-card>
241
<v-card-title>{{ item.name }}</v-card-title>
242
<v-card-text>{{ item.description }}</v-card-text>
243
</v-card>
244
</v-col>
245
</v-row>
246
</template>
247
</v-data-iterator>
248
</template>
249
```
250
251
### VList
252
253
Versatile list component for displaying items with various layouts and interactive features.
254
255
```typescript { .api }
256
/**
257
* List component for displaying collections of items
258
*/
259
const VList: Component;
260
261
interface ListProps {
262
/** List items array */
263
items?: any[];
264
/** Selected item values */
265
modelValue?: any;
266
/** Item value key */
267
itemValue?: string | ((item: any) => any);
268
/** Item title key */
269
itemTitle?: string | ((item: any) => any);
270
/** Item props key */
271
itemProps?: string | ((item: any) => any);
272
/** Item children key for nested lists */
273
itemChildren?: string | ((item: any) => any);
274
/** Return object format */
275
returnObject?: boolean;
276
/** List density */
277
density?: 'default' | 'comfortable' | 'compact';
278
/** Navigation style */
279
nav?: boolean;
280
/** Selection strategy */
281
selectStrategy?: SelectStrategy;
282
/** Open strategy for nested items */
283
openStrategy?: OpenStrategy;
284
/** Activation strategy */
285
activateStrategy?: ActiveStrategy;
286
/** List background color */
287
bgColor?: string;
288
/** Whether list items are clickable */
289
itemType?: 'item' | 'divider' | 'subheader';
290
/** Disable list interactions */
291
disabled?: boolean;
292
/** Mandatory selection */
293
mandatory?: boolean;
294
/** Multiple selection */
295
multiple?: boolean;
296
}
297
298
// Events
299
interface ListEvents {
300
'update:modelValue': (value: any) => void;
301
'update:opened': (opened: any[]) => void;
302
'click:open': (data: { id: any; value: boolean }) => void;
303
'click:select': (data: { id: any; value: boolean }) => void;
304
'click:activate': (data: { id: any; value: boolean }) => void;
305
}
306
```
307
308
**Usage Examples:**
309
310
```vue
311
<template>
312
<!-- Basic list -->
313
<v-list>
314
<v-list-item
315
v-for="item in items"
316
:key="item.id"
317
:title="item.title"
318
:subtitle="item.subtitle"
319
@click="handleClick(item)"
320
/>
321
</v-list>
322
323
<!-- Navigation list -->
324
<v-list nav density="compact">
325
<v-list-item
326
v-for="item in navItems"
327
:key="item.id"
328
:to="item.to"
329
:prepend-icon="item.icon"
330
:title="item.title"
331
/>
332
</v-list>
333
334
<!-- Selection list -->
335
<v-list
336
v-model="selected"
337
select-strategy="multiple-leaf"
338
>
339
<v-list-item
340
v-for="item in selectableItems"
341
:key="item.id"
342
:value="item.id"
343
:title="item.title"
344
/>
345
</v-list>
346
</template>
347
```
348
349
### VTable
350
351
Simple HTML table wrapper with Vuetify styling and responsive features.
352
353
```typescript { .api }
354
/**
355
* Simple table wrapper component
356
*/
357
const VTable: Component;
358
359
interface TableProps {
360
/** Table density */
361
density?: 'default' | 'comfortable' | 'compact';
362
/** Fixed header */
363
fixedHeader?: boolean;
364
/** Fixed footer */
365
fixedFooter?: boolean;
366
/** Table height */
367
height?: string | number;
368
/** Hover effect on rows */
369
hover?: boolean;
370
/** Theme variant */
371
theme?: string;
372
}
373
```
374
375
**Usage Examples:**
376
377
```vue
378
<template>
379
<v-table density="compact" hover>
380
<thead>
381
<tr>
382
<th>Name</th>
383
<th>Email</th>
384
<th>Role</th>
385
</tr>
386
</thead>
387
<tbody>
388
<tr v-for="item in items" :key="item.id">
389
<td>{{ item.name }}</td>
390
<td>{{ item.email }}</td>
391
<td>{{ item.role }}</td>
392
</tr>
393
</tbody>
394
</v-table>
395
</template>
396
```
397
398
### VTreeview
399
400
Hierarchical tree view component with expandable nodes and selection capabilities.
401
402
```typescript { .api }
403
/**
404
* Tree view component for hierarchical data
405
*/
406
const VTreeview: Component;
407
408
interface TreeviewProps {
409
/** Tree items array */
410
items?: any[];
411
/** Selected item values */
412
modelValue?: any[];
413
/** Opened/expanded nodes */
414
opened?: any[];
415
/** Activated item */
416
activated?: any[];
417
/** Item value key */
418
itemValue?: string | ((item: any) => any);
419
/** Item title key */
420
itemTitle?: string | ((item: any) => any);
421
/** Item children key */
422
itemChildren?: string | ((item: any) => any);
423
/** Item props key */
424
itemProps?: string | ((item: any) => any);
425
/** Return object format */
426
returnObject?: boolean;
427
/** Selection strategy */
428
selectStrategy?: SelectStrategy;
429
/** Open strategy */
430
openStrategy?: OpenStrategy;
431
/** Activation strategy */
432
activateStrategy?: ActiveStrategy;
433
/** Tree density */
434
density?: 'default' | 'comfortable' | 'compact';
435
/** Loading state */
436
loading?: boolean;
437
/** Load children function for lazy loading */
438
loadChildren?: (item: any) => Promise<any[]>;
439
}
440
441
// Events
442
interface TreeviewEvents {
443
'update:modelValue': (value: any[]) => void;
444
'update:opened': (opened: any[]) => void;
445
'update:activated': (activated: any[]) => void;
446
'click:open': (data: { id: any; value: boolean; path: any[] }) => void;
447
'click:select': (data: { id: any; value: boolean; path: any[] }) => void;
448
'click:activate': (data: { id: any; value: boolean; path: any[] }) => void;
449
}
450
```
451
452
**Usage Examples:**
453
454
```vue
455
<template>
456
<!-- Basic tree -->
457
<v-treeview
458
:items="treeItems"
459
item-title="name"
460
item-value="id"
461
item-children="children"
462
/>
463
464
<!-- Selectable tree -->
465
<v-treeview
466
v-model="selected"
467
:items="treeItems"
468
select-strategy="leaf"
469
open-strategy="multiple"
470
item-title="name"
471
item-value="id"
472
item-children="children"
473
/>
474
475
<!-- Lazy loading tree -->
476
<v-treeview
477
:items="lazyItems"
478
:load-children="loadChildren"
479
item-title="name"
480
item-value="id"
481
/>
482
</template>
483
484
<script setup>
485
const treeItems = ref([
486
{
487
id: 1,
488
name: 'Folder 1',
489
children: [
490
{ id: 2, name: 'File 1.1' },
491
{ id: 3, name: 'File 1.2' },
492
]
493
},
494
{
495
id: 4,
496
name: 'Folder 2',
497
children: [
498
{ id: 5, name: 'File 2.1' },
499
]
500
},
501
]);
502
503
const loadChildren = async (item) => {
504
// Simulate API call
505
await new Promise(resolve => setTimeout(resolve, 1000));
506
return [
507
{ id: `${item.id}-1`, name: `Child of ${item.name}` }
508
];
509
};
510
</script>
511
```
512
513
### VTimeline
514
515
Timeline component for displaying chronological events and milestones.
516
517
```typescript { .api }
518
/**
519
* Timeline component for chronological event display
520
*/
521
const VTimeline: Component;
522
523
interface TimelineProps {
524
/** Timeline items */
525
items?: any[];
526
/** Timeline direction */
527
direction?: 'horizontal' | 'vertical';
528
/** Alignment of timeline */
529
align?: 'start' | 'center' | 'end';
530
/** Timeline side for vertical layout */
531
side?: 'start' | 'end';
532
/** Line thickness */
533
lineThickness?: string | number;
534
/** Timeline density */
535
density?: 'default' | 'comfortable' | 'compact';
536
/** Reverse order */
537
reverse?: boolean;
538
/** Truncate line at edges */
539
truncateLine?: 'start' | 'end' | 'both';
540
}
541
```
542
543
**Usage Examples:**
544
545
```vue
546
<template>
547
<v-timeline direction="vertical" align="start">
548
<v-timeline-item
549
v-for="item in timelineItems"
550
:key="item.id"
551
:dot-color="item.color"
552
size="small"
553
>
554
<template #icon>
555
<v-icon>{{ item.icon }}</v-icon>
556
</template>
557
558
<v-card>
559
<v-card-title>{{ item.title }}</v-card-title>
560
<v-card-subtitle>{{ item.time }}</v-card-subtitle>
561
<v-card-text>{{ item.description }}</v-card-text>
562
</v-card>
563
</v-timeline-item>
564
</v-timeline>
565
</template>
566
567
<script setup>
568
const timelineItems = [
569
{
570
id: 1,
571
title: 'Project Started',
572
time: '9:00 AM',
573
description: 'Initial project setup and planning',
574
icon: 'mdi-play-circle',
575
color: 'success'
576
},
577
{
578
id: 2,
579
title: 'Development Phase',
580
time: '10:30 AM',
581
description: 'Core functionality implementation',
582
icon: 'mdi-code-tags',
583
color: 'primary'
584
}
585
];
586
</script>
587
```
588
589
### VVirtualScroll
590
591
Virtual scrolling component for efficiently rendering large lists.
592
593
```typescript { .api }
594
/**
595
* Virtual scrolling container for large datasets
596
*/
597
const VVirtualScroll: Component;
598
599
interface VirtualScrollProps {
600
/** Array of items to render */
601
items?: any[];
602
/** Height of each item */
603
itemHeight?: number | string | ((index: number) => number);
604
/** Container height */
605
height?: number | string;
606
/** Container max height */
607
maxHeight?: number | string;
608
/** Bench (buffer) size for rendering */
609
bench?: number;
610
/** Item component to render */
611
component?: string | Component;
612
/** Item props function */
613
itemProps?: (data: { item: any; index: number }) => Record<string, any>;
614
}
615
616
// Events
617
interface VirtualScrollEvents {
618
'update:modelValue': (value: any[]) => void;
619
}
620
```
621
622
**Usage Examples:**
623
624
```vue
625
<template>
626
<!-- Basic virtual scroll -->
627
<v-virtual-scroll
628
:items="largeDataset"
629
:item-height="48"
630
height="400"
631
>
632
<template #default="{ item, index }">
633
<v-list-item :title="item.name" :subtitle="item.description" />
634
</template>
635
</v-virtual-scroll>
636
637
<!-- Dynamic item heights -->
638
<v-virtual-scroll
639
:items="variableItems"
640
:item-height="(index) => getItemHeight(index)"
641
height="400"
642
>
643
<template #default="{ item }">
644
<v-card class="ma-2">
645
<v-card-text>{{ item.content }}</v-card-text>
646
</v-card>
647
</template>
648
</v-virtual-scroll>
649
</template>
650
651
<script setup>
652
const largeDataset = ref(
653
Array.from({ length: 10000 }, (_, i) => ({
654
id: i,
655
name: `Item ${i}`,
656
description: `Description for item ${i}`
657
}))
658
);
659
660
const getItemHeight = (index) => {
661
return index % 3 === 0 ? 80 : 48; // Variable heights
662
};
663
</script>
664
```
665
666
### VInfiniteScroll
667
668
Infinite scroll component for loading data incrementally as user scrolls.
669
670
```typescript { .api }
671
/**
672
* Infinite scroll loading component
673
*/
674
const VInfiniteScroll: Component;
675
676
interface InfiniteScrollProps {
677
/** Loading state */
678
loading?: boolean;
679
/** Whether there are more items to load */
680
hasMore?: boolean;
681
/** Load more function */
682
onLoad?: (options: { done: (status?: 'ok' | 'error' | 'empty') => void }) => void;
683
/** Scroll direction */
684
direction?: 'vertical' | 'horizontal';
685
/** Distance from edge to trigger load */
686
margin?: number;
687
/** Container height */
688
height?: number | string;
689
/** Maximum height */
690
maxHeight?: number | string;
691
/** Loading text */
692
loadingText?: string;
693
/** Empty state text */
694
emptyText?: string;
695
/** Error state text */
696
errorText?: string;
697
/** Color theme */
698
color?: string;
699
}
700
701
// Events
702
interface InfiniteScrollEvents {
703
'load': (options: { done: (status?: string) => void }) => void;
704
}
705
```
706
707
**Usage Examples:**
708
709
```vue
710
<template>
711
<v-infinite-scroll
712
@load="loadMore"
713
height="400"
714
:loading="loading"
715
>
716
<v-list>
717
<v-list-item
718
v-for="item in items"
719
:key="item.id"
720
:title="item.title"
721
:subtitle="item.subtitle"
722
/>
723
</v-list>
724
</v-infinite-scroll>
725
</template>
726
727
<script setup>
728
const items = ref([]);
729
const loading = ref(false);
730
const page = ref(1);
731
732
const loadMore = async ({ done }) => {
733
loading.value = true;
734
735
try {
736
const response = await fetchItems(page.value);
737
items.value.push(...response.data);
738
page.value++;
739
740
if (response.hasMore) {
741
done('ok');
742
} else {
743
done('empty'); // No more items
744
}
745
} catch (error) {
746
done('error');
747
} finally {
748
loading.value = false;
749
}
750
};
751
</script>
752
```
753
754
## Types
755
756
```typescript { .api }
757
// Filter and comparison types
758
type FilterFunction = (value: any, query: string, item: any) => boolean;
759
type FilterMatch = boolean | number | [number, number];
760
761
// Selection strategy types
762
type SelectStrategy =
763
| 'single-leaf'
764
| 'leaf'
765
| 'independent'
766
| 'single-independent'
767
| 'multiple-leaf'
768
| 'multiple-independent';
769
770
type OpenStrategy = 'single' | 'multiple' | 'list';
771
type ActiveStrategy = 'single-leaf' | 'leaf' | 'independent' | 'single-independent';
772
773
// Internal item representation
774
interface InternalItem {
775
type: 'item' | 'divider' | 'subheader';
776
title: string;
777
value: any;
778
props: Record<string, any>;
779
children?: InternalItem[];
780
raw: any;
781
}
782
```