How TanStack Table Integration Facilitates Data Table Creation in Celeris Web
Celeris Web leverages TanStack Vue-Table to provide a type-safe, declarative API for building data grids through column helpers, composable table instances, and a generic rendering component that supports features like pagination via pluggable row models.
Celeris Web, the Vue 3 admin dashboard framework in the kirklin/celeris-web repository, integrates TanStack Vue-Table to handle complex data table requirements without repetitive UI code. This TanStack Table integration allows developers to define typed columns declaratively, instantiate tables through the useVueTable composable, and render any data shape using a single generic AppTable component.
Declarative Column Definitions with createColumnHelper
The integration starts with defining column schemas using TanStack's createColumnHelper<T>() utility. This helper generates type-safe column definitions that map row properties to renderable headers and cells.
In apps/admin/src/pages/components/headless-table/basic/index.vue, columns are constructed by invoking helper methods that specify accessors, headers, and cell renderers:
const columnHelper = createColumnHelper<ChatGPTDemoTableRow>();
const columns = [
columnHelper.accessor(row => row.userInput, {
id: "userInput",
header: () => "用户输入",
// additional metadata...
}),
// additional columns...
];
Each column definition encapsulates:
- Accessor functions that extract values from row objects
- Header renderers that return the column title
- Cell renderers that format the display value
- Unique identifiers for state tracking
Building the Table Instance with useVueTable
After defining columns, developers create a reactive table instance using useVueTable. This composable accepts the column array, a data source, and row-model plugins that determine available features.
The basic implementation in apps/admin/src/pages/components/headless-table/basic/index.vue configures the core row model:
const table = useVueTable({
get data() { return chatGPTDemoTestData; },
columns,
getCoreRowModel: getCoreRowModel(),
});
To add pagination, the apps/admin/src/pages/components/headless-table/pagination/index.vue example injects an additional row model:
const table = useVueTable({
get data() { return largeDataSet; },
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
});
Key row model options include:
getCoreRowModel()– Computes the basic row/column matrix required for all tablesgetPaginationRowModel()– Enables page slicing and navigation stategetSortedRowModel()– Adds column sorting capabilitiesgetFilteredRowModel()– Supports global and column-specific filtering
Generic Rendering with the AppTable Component
Celeris Web abstracts the rendering logic into a reusable AppTable component located at apps/admin/src/component/AppTable/src/AppTable.vue. This component accepts a generic Table<T> prop and delegates header and cell rendering to TanStack's <FlexRender> component.
The component iterates over table state methods to build the UI structure:
<NTable>
<thead>
<tr v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
<th v-for="header in headerGroup.headers" :key="header.id">
<FlexRender
:render="header.column.columnDef.header"
:props="header.getContext()"
/>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in table.getRowModel().rows" :key="row.id">
<td v-for="cell in row.getVisibleCells()" :key="cell.id">
<FlexRender
:render="cell.column.columnDef.cell"
:props="cell.getContext()"
/>
</td>
</tr>
</tbody>
</NTable>
The TypeScript signature ensures type safety across any data shape:
defineProps<{ table: Table<T>; }>();
This architecture separates data logic from presentation, allowing the same UI component to render user tables, transaction logs, or inventory lists without modification.
Adding Advanced Features via Row Models
The pluggable row-model system enables sophisticated features through configuration rather than component rewriting. By including additional getters in the useVueTable options object, the AppTable component automatically gains functionality.
To implement pagination:
- Import
getPaginationRowModelfrom@tanstack/vue-table - Include it in the table configuration
- Access pagination state via
table.getState().paginationand navigation methods liketable.previousPage()
To enable sorting:
- Add
getSortedRowModel()to the configuration - Configure sortable columns in the column definitions
- Toggle sorting through
header.column.getToggleSortingHandler()
Because these features operate at the data-model level within TanStack Vue-Table, the rendering code in AppTable.vue remains unchanged regardless of which features are active.
Summary
- Type-safe columns:
createColumnHelper<T>()generates strongly typed column definitions that link row data to render functions. - Composable state:
useVueTablecreates reactive table instances that manage row models, pagination, and sorting state independently of the UI layer. - Generic rendering: The
AppTablecomponent inapps/admin/src/component/AppTable/src/AppTable.vueuses<FlexRender>to display anyTable<T>instance without prop drilling or conditional rendering logic. - Feature plugins: Advanced capabilities like pagination (
getPaginationRowModel) are enabled by adding row-model getters to the table configuration, keeping the component surface area minimal.
Frequently Asked Questions
How does Celeris Web handle type safety in TanStack Table columns?
Celeris Web uses createColumnHelper<T>() to maintain end-to-end type safety from the row data structure through to the cell renderers. When defining columns in files like apps/admin/src/pages/components/headless-table/basic/index.vue, the generic type parameter ensures that accessor functions and cell context values are properly typed, preventing runtime errors from mismatched property access.
What is the role of FlexRender in the AppTable component?
<FlexRender> is TanStack Vue-Table's rendering utility that invokes the header and cell functions defined in column configurations. In apps/admin/src/component/AppTable/src/AppTable.vue, it receives the render function from the column definition and the context object (containing row data, column state, and table instance), executing the appropriate Vue render function to produce the final DOM output.
Can I add sorting and filtering without modifying the AppTable component?
Yes. According to the source code patterns in apps/admin/src/pages/components/headless-table/pagination/index.vue, features like sorting and filtering are enabled by importing the corresponding row-model plugins (e.g., getSortedRowModel, getFilteredRowModel) and passing them to useVueTable. The AppTable component automatically adapts to these features because it reads from the standard table.getRowModel() and table.getHeaderGroups() APIs regardless of which plugins are active.
Where is the TanStack Vue-Table dependency declared in the repository?
The dependency is declared in pnpm-workspace.yaml as @tanstack/vue-table version ^8.21.3, making it available throughout the Celeris Web monorepo for use in admin components and page implementations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →