gp-grid-logo
API Reference

Data Sources

Connect the Vue 3 grid to client-side arrays or server-side endpoints, and plug streaming, paginated, or fully remote data flows into gp-grid with ease.

gp-grid provides data source abstractions shared with the React package.

Basic Usage

<script setup>
const data = ref([
  { id: 1, name: "Giovanni" },
  { id: 2, name: "Luca" },
]);
</script>

<template>
  <Grid :row-data="data" ... />
</template>

Client Data Source

<script setup>
import { createClientDataSource } from "@gp-grid/vue";

const dataSource = createClientDataSource(largeDataset, {
  useWorker: true,  // Web Worker for sorting
});
</script>

<template>
  <Grid :data-source="dataSource" ... />
</template>

Mutable Data Source

For CRUD operations, use the useGridData composable inside <script setup>. It wraps createMutableClientDataSource with a stable reference and exposes addRows / removeRows helpers bound to the current data source.

<script setup>
import { useGridData } from "@gp-grid/vue";

const { dataSource, addRows, removeRows } = useGridData(data, {
  getRowId: (row) => row.id,
});

function addRow() {
  addRows([{ id: Date.now(), name: "New" }]);
}

function updateRow(id: number, name: string) {
  dataSource.updateCell(id, "name", name);
}

function deleteRow(id: number) {
  removeRows([id]);
}
</script>

Reach for the raw createMutableClientDataSource factory only outside components — module-level singletons, composables that need their own lifecycle, or shared utilities. Inside a component, prefer useGridData: it handles subscription cleanup on unmount and keeps the dataSource reference stable across re-renders.

// Outside a component (e.g. a shared module)
import { createMutableClientDataSource } from "@gp-grid/vue";

export const sharedDataSource = createMutableClientDataSource(seed, {
  getRowId: (row) => row.id,
});

useGridData Options

interface UseGridDataOptions<TData> {
  getRowId: (row: TData) => RowId;     // Required: unique ID accessor
  debounceMs?: number;                  // Batch window (default: 50)
  useWorker?: boolean;                  // Use Web Worker for sorting (default: true)
  parallelSort?: ParallelSortOptions | false;
}

MutableDataSource Methods

interface MutableDataSource<TData> extends DataSource<TData> {
  addRows(rows: TData[]): void;
  removeRows(ids: RowId[]): void;
  updateCell(id: RowId, field: string, value: CellValue): void;
  updateRow(id: RowId, data: Partial<TData>): void;
  flushTransactions(): Promise<void>;
  hasPendingTransactions(): boolean;
  getDistinctValues(field: string): CellValue[];
  getRowById(id: RowId): TData | undefined;
  getTotalRowCount(): number;
  subscribe(listener: DataChangeListener): () => void;
  clear(): void;
  moveRow(fromIndex: number, toIndex: number): void;
}

DataSource Interface

All data sources implement the DataSource<TData> interface. Both createClientDataSource and createServerDataSource return objects that conform to it; MutableDataSource<TData> extends it with mutation methods.

interface DataSource<TData> {
  readonly loadMode?: "all" | "paginated";
  query(request: DataSourceRequest): Promise<DataSourceResponse<TData>>;
  destroy?(): void;
  moveRow?(fromIndex: number, toIndex: number): void;
}
MemberRequiredDescription
loadModeNo"all" (default for client data sources) or "paginated" (default for server). Controls whether the grid requests every row at once or only the visible window via range.startRow / range.endRow.
queryYesAsync function returning { rows, totalRows } for the requested range, sort, and filter. Called by the grid whenever the visible window, sort, or filter changes.
destroyNoCleanup hook for releasing workers, sockets, or other resources. Called when the data source is detached from the grid.
moveRowNoCalled on row drag-end. Implement it to update the underlying data; the grid does not mutate data on its own.

Server Data Source

<script setup>
import { createServerDataSource } from "@gp-grid/vue";

const dataSource = createServerDataSource(async (request) => {
  const { range, sort, filter } = request;

  const response = await fetch("/api/data", {
    method: "POST",
    body: JSON.stringify({
      startRow: range.startRow,
      endRow: range.endRow,
      sortBy: sort,
      filters: filter,
    }),
  });
  return response.json();
});
</script>

<template>
  <Grid :data-source="dataSource" ... />
</template>

Pass { loadMode: "all" } as a second argument if the server returns the entire result set in one call. The default is "paginated" — the grid only requests the row window currently in view via range.startRow / range.endRow.

const dataSource = createServerDataSource(queryFn, { loadMode: "paginated" });

Request / Response

interface DataSourceRequest {
  range: {
    startRow: number; // First row index to fetch (0-indexed, inclusive)
    endRow: number;   // First row index after the range (exclusive)
  };
  sort?: SortModel[];
  filter?: FilterModel;
}

interface DataSourceResponse<TData> {
  rows: TData[];
  totalRows: number;
}

With Nuxt useFetch

<script setup>
const dataSource = createServerDataSource(async (request) => {
  return await $fetch("/api/grid-data", {
    method: "POST",
    body: request,
  });
});
</script>

Reactive Updates

Data sources work with Vue's reactivity:

<script setup>
const data = ref<User[]>([]);

// Fetch initial data
onMounted(async () => {
  data.value = await fetchUsers();
});

// Grid automatically updates when data.value changes
</script>

<template>
  <Grid :row-data="data" ... />
</template>

On this page