Row Selection
useRowSelection() — dataset-agnostic click / Shift-click row selection — works with VirtualList, VirtualTable, or any plain array. Not tied to a specific component: pair isSelected/toggle with whichever row-index slot scope your component exposes.
function useRowSelection<T>(options: UseRowSelectionOptions<T>): UseRowSelectionReturn<T>Options
items
Ref<T[]> | ComputedRef<T[]>
Reactive items array.
getKey
(item: T, index: number) => string | number · default: item.id ?? index
Identity used for the selection set.
multiple
boolean · default: true
false restricts to a single selected row; a new toggle call replaces the selection instead of adding to it.
Return value
selectedKeys
Readonly<Ref<Set<string | number>>>
Currently selected keys.
selectedItems
ComputedRef<T[]>
Currently selected items, derived from items + selectedKeys.
isSelected
(item: T, index: number) => boolean
Whether a row is selected.
toggle
(item: T, index: number, event?: MouseEvent | KeyboardEvent) => void
Toggle a row. event.shiftKey fills the range from the last-toggled row to this one (Gmail-checkbox convention), on top of whatever's already selected.
selectAll
() => void
Select every row in items.
clearSelection
() => void
Clear the selection and reset the shift-range anchor.
Example
<script setup lang="ts">
import { ref } from 'vue'
import { VirtualList, useRowSelection } from 'vue-virtual-scroller-kit'
interface Row {
id: number
label: string
}
const items = ref<Row[]>(Array.from({ length: 1000 }, (_, i) => ({ id: i, label: `Row ${i + 1}` })))
const selection = useRowSelection<Row>({ items })
</script>
<template>
<VirtualList :items="items" key-field="id" :estimated-item-size="40" style="height: 500px">
<template #default="{ item, index }">
<label>
<input
type="checkbox"
:checked="selection.isSelected(item, index)"
@click="selection.toggle(item, index, $event)"
/>
{{ item.label }}
</label>
</template>
</VirtualList>
<p>{{ selection.selectedItems.value.length }} selected</p>
</template>Click toggles one row in place; Shift+click fills the range from the last-toggled row. For
VirtualTable, pair this with theindexnow available on the#cellslot — see the row-selection example on the VirtualTable page.