Vue migration to version 1.0
Migrate the Vue gp-grid wrapper from 0.23.x to 1.0 with before-and-after examples for public exports, callback props, column state, refs, writes, and refresh.
This guide is for Vue.
Using another framework? Select the correct guide.
This guide covers migrating @gp-grid/vue from 0.23.x to 1.0. It focuses on the component integration; use the shared core migration reference for custom adapters and the complete imperative API mapping.
Upgrade packages
bun add @gp-grid/vue@^1.0.0Upgrade any other installed @gp-grid/* packages together. Keep importing the stylesheet once:
import "@gp-grid/vue/dist/styles.css";Upgrade Vue to ^3.5.0; the component uses useId. Import the component as GpGrid or the package default.
The package no longer exports component internals: useInputHandler, useAutoScroll, useFillHandle, useFilterPopup, useFilterConditions, useGridState, createInitialState, renderCell, renderEditCell, renderHeader, getCellValue, or their option/result types.
Shared core helpers and types are also no longer re-exported here: buildCellClasses, isCellActive, isCellEditing, isCellInFillPreview, isCellSelected, calculateColumnPositions, findColumnAtX, getTotalWidth, isRowVisible, FilterPopupState, HeaderData, PointerEventData, and SelectionState. Import these from @gp-grid/core instead. The public useGpGrid and useGridData composables remain available.
import { isCellSelected } from "@gp-grid/vue";import { isCellSelected } from "@gp-grid/core";Events carry identity
Interaction callbacks now receive one object with stable identity and named view indices. There is no compatibility adapter for positional arguments or the old payloads.
Callbacks are props. Bind them with :on-column-resized, :on-column-moved, and :on-row-drag-end.
function handleColumnResized(colIndex: number, newWidth: number) {
persistWidth(colIndex, newWidth);
}
function handleColumnMoved(fromIndex: number, toIndex: number) {
persistOrder(fromIndex, toIndex);
}
function handleRowDragEnd(sourceIndex: number, targetIndex: number) {
dataSource.moveRow(sourceIndex, targetIndex);
}<script setup lang="ts">
import type { ColumnResizedEvent, ColumnMovedEvent, RowDragEndEvent } from "@gp-grid/vue";
function handleColumnResized({ columnId, width, viewIndex }: ColumnResizedEvent) {
persistWidth(columnId, width, viewIndex);
}
function handleColumnMoved({ columnId, fromViewIndex, toViewIndex }: ColumnMovedEvent) {
persistOrder(columnId, fromViewIndex, toViewIndex);
}
function handleRowDragEnd({ fromViewIndex, toViewIndex }: RowDragEndEvent) {
dataSource.moveRow(fromViewIndex, toViewIndex);
}
</script>
<template>
<GpGrid
:columns="columns"
:data-source="dataSource"
:row-height="36"
:on-column-resized="handleColumnResized"
:on-column-moved="handleColumnMoved"
:on-row-drag-end="handleRowDragEnd"
/>
</template>RowDragEndEvent also includes rowId. Column indices describe the resolved layout; persist state by identity. CellValueChangedEvent now includes columnId. A resize with no committed change fires no event.
Column definitions and column state
Definitions are immutable inputs. The core owns live order, widths, visibility, and pins by colId ?? field. Remove code that depends on the grid mutating a definition or requires you to reorder the columns array after a drag. A column-move callback is a notification of the committed move.
Use the controlled columnState input for explicit overrides:
<GpGrid :columns="columns" :column-state="[{ columnId: 'city', width: 240 }]" :row-data="data" :row-height="36" />Replacing columns keeps the core instance and retains state, sorting, and filtering for surviving column ids. Removed ids lose their state. Definition changes apply only where no user override exists.
To save state, read core.columns.getState(). To restore a saved snapshot after further edits, call core.columns.resetState() before core.columns.setState(savedState). width is an explicit override; resolvedWidth is output-only and is zero while hidden. Invalid widths fall back to 50 px.
Imperative API access
A component template ref still exposes core.
gridRef.value?.core?.setSort("name", "asc");
gridRef.value?.core?.startEdit(0, 1);gridRef.value?.core?.sortFilter.setSort("name", "asc");
gridRef.value?.core?.edit.start(0, 1);Other common moves are getRowCount() → rows.getCount(), getRowData(i) → rows.getData(i), and setCellValue(row, col, value) → cells.setValue(row, col, value). There are no root-level forwarding methods. See the complete namespace mapping.
Editing, writes, and refresh
- Editor commits are coerced by
cellDataType: a number-column draft"60000"stores60000. An invalid draft writes nothing and reportstype-mismatchthroughonWriteRejected. onWriteCommittedreports one event per edit, paste, fill, or programmatic write, including skipped targets. It requiresgetRowId;history: { maxEntries }enables bounded undo and redo and also requiresgetRowId.- Columnar sources are read-only. Group and total rows cannot be edited; writes report
not-a-record. Row dragging is disabled while a hierarchy is bound. core.rows.getData(i)returns a resident source record only. UsegetViewRow(i)and narrow onkindbefore reading a hierarchical record; columnar rows have no materialized record.- Mutable source subscriptions are handled by the wrapper. Update-only transactions redraw changed rows without a query, preserving row position even if a sorted or filtered field changes. Call
core.refresh()to re-sort or re-filter immediately. Adds, removes, and clearing reload the view.
Labels, sizing, and server rendering
GridLabelOverrides remains partial. A full GridLabels object must add pinLeftColumn, pinRightColumn, unpinColumn, frozenRowsLimited, columnSchemaErrors, and rowGroups including loadFailed.
The header stays fixed. Cells fill their row height through the shipped stylesheet; remove custom inline cell heights that conflict with the row box. Rows resize only through application commands, gestures, or one-shot fit, rather than growing automatically with content.
Pass initialWidth and initialHeight for server rendering. Controlled columnState and columnLayout seed the initial layout. Header bands use configured heights until client measurements refine them.
ARIA row indices include header bands, and aria-rowcount includes the headers. Hierarchical views use role="treegrid", and core.rows.getCount() includes groups and totals. Sort, filter-popup, and pin header controls remain pointer-only.
Shared core changes
Review the core migration reference if you consume geometry, instructions, complete label objects, saved filters, or custom adapter types. It covers exclusive window ends, required slot heights and row regions, removed exports, schema command return values, and legacy filter normalization.
Source: upstream migration guide.