Skip to content

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

ts
import { useDataTable } from '@almighty-shogun/common'

Usage

vue
<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

ts
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;
};

Uses

All packages are released under the MIT License.