useDataTable
Combines a reactive item collection with pagination state and exposes the current visible slice as filteredItems. This composable is intended for client-side tables where the full dataset is already available in memory and only the rendered page needs to change.
It watches the length of the source item array and keeps total synchronized automatically. Changing page or perPage immediately changes the computed slice; it does not fetch data from an API and does not mutate the source items.
Importing
import { useDataTable } from '@almighty-shogun/common'Usage
<template>
<p v-if="isEmpty">No users found.</p>
<table v-else>
<tr v-for="user in filteredItems" :key="user.id">
<td>{{ user.name }}</td>
</tr>
</table>
<select :value="perPage" @change="setPerPage(Number(($event.target as HTMLSelectElement).value))">
<option v-for="limit in limits" :key="limit" :value="limit">
{{ limit }}
</option>
</select>
<button :disabled="page <= 1" @click="setPage(page - 1)">Previous</button>
<button :disabled="page * perPage >= total" @click="setPage(page + 1)">Next</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useDataTable } from '@almighty-shogun/common'
type User = { id: number; name: string };
const users = ref<User[]>([
{ id: 1, name: 'Ada' },
{ id: 2, name: 'Grace' },
{ id: 3, name: 'Linus' }
]);
const {
filteredItems,
isEmpty,
page,
perPage,
total,
limits,
setPage,
setPerPage
} = useDataTable(users, 10);
</script>Parameters
items: Ref<T[]>
Reactive array containing the full collection that should be paginated.
pageSize?: number
Initial number of items per page.
Default: 5
Returns
isEmpty: Ref<boolean>true when the current source collection contains no items.
total: Ref<number>
Total number of source items. It is updated when items.value.length changes.
page: Ref<number>
One-based active page number.
perPage: Ref<number>
Active page size.
limits: Ref<number[]>
Available page-size options: [5, 10, 25, 50, 100].
filteredItems: Ref<T[]>
Computed slice for the active page and page size.
setTotal(total: number): void
Manually overrides the total. Usually not needed because the watcher syncs it.
setPage(page: number): void
Changes the active page.
setPerPage(perPage: number): void
Changes the active page size.
Type signature
declare function useDataTable<T>(
items: Ref<T[]>,
pageSize?: number
): UseDataTable<T>;
type UseDataTable<T> = {
readonly isEmpty: Ref<boolean>;
readonly total: Ref<number>;
readonly page: Ref<number>;
readonly perPage: Ref<number>;
readonly limits: Ref<number[]>;
readonly filteredItems: Ref<T[]>;
setTotal(total: number): void;
setPage(page: number): void;
setPerPage(perPage: number): void;
};