Nuxt Integration
Using gp-grid with Nuxt 3
Nuxt Integration
gp-grid works seamlessly with Nuxt 3. This guide covers Nuxt-specific setup and patterns.
Installation
pnpm add gp-grid-vueBasic Usage
Create a component or use directly in pages:
<!-- pages/grid.vue -->
<script setup lang="ts">
import { Grid, type ColumnDefinition } from "gp-grid-vue";
const columns: ColumnDefinition[] = [
{ field: "id", cellDataType: "number", width: 80, headerName: "ID" },
{ field: "name", cellDataType: "text", width: 200, headerName: "Name" },
];
const { data } = await useFetch("/api/users");
</script>
<template>
<div class="h-[500px]">
<Grid
v-if="data"
:columns="columns"
:row-data="data"
:row-height="36"
/>
</div>
</template>Client-Only Rendering
Since gp-grid requires browser APIs, wrap it in <ClientOnly> for SSR:
<template>
<ClientOnly>
<div class="h-[500px]">
<Grid :columns="columns" :row-data="data" :row-height="36" />
</div>
<template #fallback>
<div class="h-[500px] flex items-center justify-center">
Loading grid...
</div>
</template>
</ClientOnly>
</template>Dark Mode with Color Mode
Using @nuxtjs/color-mode:
<script setup lang="ts">
import { Grid } from "gp-grid-vue";
const colorMode = useColorMode();
const isDark = computed(() => colorMode.value === "dark");
</script>
<template>
<ClientOnly>
<Grid
:columns="columns"
:row-data="data"
:row-height="36"
:dark-mode="isDark"
/>
</ClientOnly>
</template>Server-Side Data with API Routes
API Route
// server/api/grid-data.post.ts
import { defineEventHandler, readBody } from "h3";
export default defineEventHandler(async (event) => {
const { pagination, sort, filter } = await readBody(event);
// Query your database
const results = await db.query({
offset: pagination.pageIndex * pagination.pageSize,
limit: pagination.pageSize,
orderBy: sort,
where: filter,
});
return {
rows: results.data,
totalRows: results.total,
};
});Component
<script setup lang="ts">
import { Grid, createServerDataSource } from "gp-grid-vue";
const dataSource = createServerDataSource(async (request) => {
return await $fetch("/api/grid-data", {
method: "POST",
body: request,
});
});
</script>
<template>
<ClientOnly>
<div class="h-[500px]">
<Grid
:columns="columns"
:data-source="dataSource"
:row-height="36"
/>
</div>
</ClientOnly>
</template>Composable Pattern
Create a reusable composable:
// composables/useGrid.ts
import { type ColumnDefinition } from "gp-grid-vue";
export function useGrid<T>(columns: ColumnDefinition[], fetchFn: () => Promise<T[]>) {
const data = ref<T[]>([]);
const loading = ref(true);
const error = ref<Error | null>(null);
async function refresh() {
loading.value = true;
try {
data.value = await fetchFn();
} catch (e) {
error.value = e as Error;
} finally {
loading.value = false;
}
}
onMounted(refresh);
return {
columns,
data,
loading,
error,
refresh,
};
}Usage:
<script setup lang="ts">
const { columns, data, loading } = useGrid(
[
{ field: "id", cellDataType: "number", width: 80 },
{ field: "name", cellDataType: "text", width: 200 },
],
() => $fetch("/api/users")
);
</script>
<template>
<ClientOnly>
<div v-if="loading">Loading...</div>
<Grid v-else :columns="columns" :row-data="data" :row-height="36" />
</ClientOnly>
</template>TypeScript Configuration
Ensure TypeScript is configured in nuxt.config.ts:
export default defineNuxtConfig({
typescript: {
strict: true,
},
});