Skip to content

Commit 9d835e6

Browse files
docs(VDataTableVirtual): add example with itemRef slot prop (#22120)
Add example with itemRef slot prop when using VDataTableVirtual
1 parent 4eeb514 commit 9d835e6

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<template>
2+
<v-app>
3+
<v-container>
4+
<v-chip-group v-model="selectedSize" class="mb-4" mandatory row>
5+
<v-chip
6+
v-for="size in sizes"
7+
:key="size"
8+
:value="size"
9+
color="primary"
10+
variant="outlined"
11+
>
12+
{{ size }} items
13+
</v-chip>
14+
</v-chip-group>
15+
16+
<v-data-table-virtual
17+
:headers="headers"
18+
:items="items"
19+
height="400"
20+
item-key="id"
21+
fixed-header
22+
>
23+
<template v-slot:item="{ columns, internalItem, props, itemRef }">
24+
<tr v-bind="props" :ref="itemRef">
25+
<td v-for="column in columns" :key="column.key">
26+
{{ internalItem.raw[column.key] }}
27+
</td>
28+
</tr>
29+
</template>
30+
</v-data-table-virtual>
31+
</v-container>
32+
</v-app>
33+
</template>
34+
35+
<script setup>
36+
import { computed, ref } from 'vue'
37+
38+
const sizes = [100, 400, 800]
39+
const selectedSize = ref(100)
40+
41+
const headers = [
42+
{ title: 'ID', value: 'id', sortable: true },
43+
{ title: 'Title', value: 'title', sortable: true },
44+
{ title: 'Name', value: 'name', sortable: true },
45+
{ title: 'Email', value: 'email', sortable: true },
46+
{ title: 'Role', value: 'role', sortable: true },
47+
]
48+
49+
const baseItems = [
50+
{ title: 'Mr.', name: 'James Smith', email: '[email protected]', role: 'Owner' },
51+
{ title: 'Ms.', name: 'Mary Johnson', email: '[email protected]', role: 'Manager' },
52+
{ title: 'Dr.', name: 'Robert Williams', email: '[email protected]', role: 'Board Member' },
53+
{ title: 'Mrs.', name: 'Patricia Brown', email: '[email protected]', role: 'Developer' },
54+
{ title: 'Mr.', name: 'John Davis', email: '[email protected]', role: 'Designer' },
55+
{ title: 'Ms.', name: 'Jennifer Garcia', email: '[email protected]', role: 'Manager' },
56+
{ title: 'Mr.', name: 'Michael Miller', email: '[email protected]', role: 'Owner' },
57+
{ title: 'Mrs.', name: 'Linda Martinez', email: '[email protected]', role: 'Developer' },
58+
{ title: 'Dr.', name: 'William Rodriguez', email: '[email protected]', role: 'Board Member' },
59+
{ title: 'Ms.', name: 'Elizabeth Hernandez', email: '[email protected]', role: 'Designer' },
60+
{ title: 'Mr.', name: 'David Lopez', email: '[email protected]', role: 'Manager' },
61+
{ title: 'Mrs.', name: 'Barbara Gonzalez', email: '[email protected]', role: 'Owner' },
62+
]
63+
64+
const items = computed(() => {
65+
return Array.from({ length: selectedSize.value }).map((_, i) => {
66+
const base = baseItems[i % baseItems.length]
67+
return { id: i + 1, ...base }
68+
})
69+
})
70+
</script>
71+
72+
<script>
73+
export default {
74+
data () {
75+
return {
76+
sizes: [100, 400, 800],
77+
selectedSize: 100,
78+
headers: [
79+
{ title: 'ID', value: 'id', sortable: true },
80+
{ title: 'Title', value: 'title', sortable: true },
81+
{ title: 'Name', value: 'name', sortable: true },
82+
{ title: 'Email', value: 'email', sortable: true },
83+
{ title: 'Role', value: 'role', sortable: true },
84+
],
85+
baseItems: [
86+
{ title: 'Mr.', name: 'James Smith', email: '[email protected]', role: 'Owner' },
87+
{ title: 'Ms.', name: 'Mary Johnson', email: '[email protected]', role: 'Manager' },
88+
{ title: 'Dr.', name: 'Robert Williams', email: '[email protected]', role: 'Board Member' },
89+
{ title: 'Mrs.', name: 'Patricia Brown', email: '[email protected]', role: 'Developer' },
90+
{ title: 'Mr.', name: 'John Davis', email: '[email protected]', role: 'Designer' },
91+
{ title: 'Ms.', name: 'Jennifer Garcia', email: '[email protected]', role: 'Manager' },
92+
{ title: 'Mr.', name: 'Michael Miller', email: '[email protected]', role: 'Owner' },
93+
{ title: 'Mrs.', name: 'Linda Martinez', email: '[email protected]', role: 'Developer' },
94+
{ title: 'Dr.', name: 'William Rodriguez', email: '[email protected]', role: 'Board Member' },
95+
{ title: 'Ms.', name: 'Elizabeth Hernandez', email: '[email protected]', role: 'Designer' },
96+
{ title: 'Mr.', name: 'David Lopez', email: '[email protected]', role: 'Manager' },
97+
{ title: 'Mrs.', name: 'Barbara Gonzalez', email: '[email protected]', role: 'Owner' },
98+
],
99+
}
100+
},
101+
102+
computed: {
103+
items () {
104+
return Array.from({ length: this.selectedSize }).map((_, i) => {
105+
const base = this.baseItems[i % this.baseItems.length]
106+
return { id: i + 1, ...base }
107+
})
108+
},
109+
},
110+
}
111+
</script>

packages/docs/src/pages/en/components/data-tables/virtual-tables.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ The v-data-table-virtual component relies on all data being available locally. B
3535
### Basic example
3636

3737
<ExamplesExample file="v-data-table/virtual" />
38+
39+
When customizing rows with the `#item` slot, you must bind the provided `itemRef` to your `<tr>`. This ensures that the virtual scroller can correctly measure and recycle rows.
40+
41+
<ExamplesExample file="v-data-table/virtual-custom" />

0 commit comments

Comments
 (0)