DataTable for Quasar
🇪🇸 Versión en español | 🇧🇷 Versão em português
Quasar extension with a homologated DataTable: shell over QTable, unified client/server pagination, and cards on viewports < sm.
Table of contents
- In 30 seconds
- What it is and what it includes
- Requirements and compatibility
- Install in a Quasar app
- What the extension adds to the host
- Global defaults (boot)
- Quick start
- Language (i18n)
- TypeScript in your IDE
DataTablecomponent API- Client-side pagination
- Server-side pagination
- Mobile layout (grid / cards)
- Compact reference
- Public entrypoints
- Troubleshooting
In 30 seconds
- Install the extension:
quasar ext add @benjaminor-dev/datatable. - Import
DataTablein your Vue component. - Pass
rows,columns,row-key, andv-model:pagination. - Add
client-paginationfor built-in client pagination (orserver-pagination+ emits when you control the backend).
The extension registers CSS and a defaults boot in the host automatically.
What it is and what it includes
DataTable is a presentation layer over Quasar QTable: optional bordered shell, pagination bar (TablePaginationBar), and card layout on mobile.
- Client pagination (
client-pagination) or server pagination (server-pagination+ emits). - Bar placement:
auto|top|bottom|both(withauto, top bar only when the current page shows ≥ 15 rows). - Built-in rows-per-page ladder (5…300) and “All” when applicable.
- Shared mobile breakpoint (
useDataTableGridLayout) — cards below< 600px. #itemslot for custom cards; default card included.- Exportable helpers to orchestrate pagination in upper layers of your app.
- Built-in i18n
en,es,pt— pagination bar follows$q.lang; optional boot overrides (locale,messages).
Requirements and compatibility
| Item | Value |
|---|---|
| Node | >= 20.0.0 |
| Quasar | ^2.6.0 |
| Vue | ^3.4.18 |
| Package format | ES modules |
| Recommended CLI | @quasar/app-vite ^2.x or ^3.x |
Install in a Quasar app
quasar ext add @benjaminor-dev/datatable
After quasar ext add, the extension registers CSS and the defaults boot automatically. No extra steps for a normal npm install.
Remove:
quasar ext remove @benjaminor-dev/datatable
Removes the generated defaults boot and its quasar.config entry. Stylesheet injection may remain if another installed package registers the same CSS path.
What the extension adds to the host
| Resource | Host path |
|---|---|
| Styles | ~@benjaminor-dev/quasar-app-extension-datatable/main.css |
| Host defaults boot | src/boot/bor/bor-datatable-defaults.ts — created on install; Skip/Overwrite if it exists |
Install (quasar ext add / invoke): creates src/boot/bor/bor-datatable-defaults.ts (or .js) and registers it in quasar.config → boot: [] automatically. No manual editing needed in a normal install. main.css is injected on every dev/build (it does not appear as a short entry in quasar.config).
Remove (quasar ext remove): removes the defaults boot and its quasar.config entry when the extension created it.
Boot order (this extension):
1. bor/bor-datatable-defaults (host)
2. rest of your boots
In quasar.config you only see bor/bor-datatable-defaults; main.css is injected by the extension at compile time.
Global defaults (boot)
Edit src/boot/bor/bor-datatable-defaults.ts after install to pin locale or override pagination strings:
import { configureDataTableDefaults } from "@benjaminor-dev/quasar-app-extension-datatable";
configureDataTableDefaults({
// locale: "es", // pin en | es | pt; omit to follow $q.lang
// messages: { allRows: "Show all" },
});
configureDataTable is an alias of configureDataTableDefaults. Priority: boot locale → $q.lang.isoName → en; boot messages merge over the built-in catalog.
Quick start
<script setup lang="ts">
import { ref } from "vue";
import DataTable from "@benjaminor-dev/quasar-app-extension-datatable";
import type { ClientTablePaginationState } from "@benjaminor-dev/quasar-app-extension-datatable/types";
const rows = [
{ id: 1, name: "Ana", role: "Admin" },
{ id: 2, name: "Luis", role: "Editor" },
];
const columns = [
{ name: "name", label: "Name", field: "name", align: "left" as const },
{ name: "role", label: "Role", field: "role", align: "left" as const },
];
const pagination = ref<ClientTablePaginationState>({
sortBy: "name",
descending: false,
page: 1,
rowsPerPage: 10,
});
</script>
<template>
<DataTable
v-model:pagination="pagination"
:rows="rows"
:columns="columns"
row-key="id"
:client-pagination="{ defaultPageSize: 10 }"
/>
</template>
Language (i18n)
Built-in en, es, and pt. By default the pagination bar follows Quasar language ($q.lang.isoName); if Quasar has no language, fallback is en.
Locale resolution: boot locale → $q.lang.isoName prefix (es* → es, pt* → pt) → en.
| Option | When to use |
|---|---|
framework.lang in quasar.config.ts |
Recommended — aligns DataTable with the rest of Quasar |
locale: 'es' in boot |
Pin a specific language (en | es | pt); ignores $q.lang changes |
messages: { allRows: '…' } in boot |
Change one string without setting locale |
Quasar config example (Spanish for the whole app):
// quasar.config.ts
framework: {
lang: "es",
},
Built-in message keys: navigation aria labels, rows-per-page labels, page indicator ({page}, {lastPage}), range format ({start}, {end}, {total}), and allRows.
TypeScript in your IDE
Do not memorize the API — let autocomplete guide you.
Import types from
@benjaminor-dev/quasar-app-extension-datatable/types(or the main entry for components and helpers).In VS Code / Cursor: Ctrl+Space / Cmd+Space inside
client-paginationorserver-paginationto see valid props (DataTableClientPaginationConfig,DataTableServerPaginationConfig).Hover
<DataTable>props: the tooltip shows JSDoc and QuasarQTabletypes where applicable.v-model:paginationis typed asClientTablePaginationState— compatible with theQTablepagination model.useDataTableGridLayout()returnsRef<boolean>; with strict TS in templates, usecomputed(() => layoutRef.value)if:griddoes not unwrap the ref.In
configureDataTableDefaults({ … })(boot), Ctrl+Space / Cmd+Space listslocale,messages, andDataTableMessageskeys.
import DataTable, {
useDataTableGridLayout,
buildDynamicRowsPerPageOptions,
} from "@benjaminor-dev/quasar-app-extension-datatable";
import type {
ClientTablePaginationState,
DataTableServerPaginationConfig,
DataTablePaginationPlacement,
} from "@benjaminor-dev/quasar-app-extension-datatable/types";
DataTable component API
| Prop | Type | Default | Description |
|---|---|---|---|
rows |
readonly Record<string, unknown>[] |
— | Rows to display |
columns |
QTableProps['columns'] |
— | Quasar columns |
row-key |
string | fn |
— | Row key |
grid |
boolean |
auto | true = cards; false = table on mobile; omitted = cards below < sm |
bordered |
boolean |
true |
Shell border |
flat |
boolean |
true |
QTable flat |
dense |
boolean |
true |
QTable dense |
client-pagination |
DataTableClientPaginationConfig |
— | Built-in client pagination |
server-pagination |
DataTableServerPaginationConfig |
— | Server state + bar |
pagination-placement |
DataTablePaginationPlacement |
'auto' |
Bar position |
selection |
'single' | 'multiple' |
— | Row selection |
loading |
boolean |
false |
Loading state |
hide-pagination |
boolean |
true |
Hides native QTable pagination |
Emits (server mode): pageSizeChange, first, previous, next, last.
Slots: item (grid card), top, bottom, standard QTable column slots.
Client-side pagination
<DataTable
v-model:pagination="pagination"
:rows="rows"
:columns="columns"
row-key="id"
:client-pagination="{
defaultPageSize: 10,
placement: 'auto',
pageSizeLadder: [5, 10, 25, 50],
}"
/>
- The bar is hidden when
totalRowsdoes not exceed the first ladder step. - Built-in ladder: “All” when
5 ≤ total ≤ 100. - Custom
pageSizeLadder: no “All” option.
Server-side pagination
The parent controls pagination and listens to emits. Pass derived state in server-pagination:
import type { DataTableServerPaginationConfig } from "@benjaminor-dev/quasar-app-extension-datatable/types";
const serverPagination = computed<DataTableServerPaginationConfig>(() => ({
totalRows: store.total,
pageSize: store.pageSize,
lastPage: store.lastPage,
pageSizeOptions: store.pageSizeOptions,
rangeLabel: store.rangeLabel,
enabled: store.hasSearched,
}));
The same helpers (buildDynamicRowsPerPageOptions, resolveDataTablePaginationPlacement, …) are exportable from this package.
Mobile layout (grid / cards)
By default, viewports ≤ 599px use grid layout (cards).
<script setup lang="ts">
import { computed } from "vue";
import { useDataTableGridLayout } from "@benjaminor-dev/quasar-app-extension-datatable";
const isMobileGridRef = useDataTableGridLayout();
const isMobileGrid = computed(() => isMobileGridRef.value);
</script>
<template>
<DataTable :grid="isMobileGrid" ... />
</template>
Custom card via #item slot:
<template #item="props">
<MyCard :row="props.row" :cols="props.cols" />
</template>
Compact reference
| Symbol | Entry | Note |
|---|---|---|
DataTable |
. |
Main component (default export) |
TablePaginationBar |
. |
Standalone bar |
useClientTablePagination |
. |
Client logic + handlers |
useDataTableGridLayout |
. |
Mobile breakpoint (singleton) |
buildDynamicRowsPerPageOptions |
. / /types |
Page-size selector options |
resolveDataTablePaginationPlacement |
. / /types |
top / bottom from placement |
shouldShowDataTablePaginationBar |
. / /types |
Show bar? |
ClientTablePaginationState |
/types |
v-model:pagination |
DataTableClientPaginationConfig |
/types |
client-pagination prop |
DataTableServerPaginationConfig |
/types |
server-pagination prop |
DataTablePaginationPlacement |
/types |
'auto' | 'top' | 'bottom' | 'both' |
| configureDataTableDefaults | . / /types | Global i18n / locale boot |
| ExtensionLocale | /types | "en" \| "es" \| "pt" |
Full type list and reexports: import /types and use IDE autocomplete.
If something is missing from autocomplete, check the import (/types vs main entry) before searching the README.
Public entrypoints
| Entrypoint | Contents |
|---|---|
@benjaminor-dev/quasar-app-extension-datatable |
DataTable, TablePaginationBar, composables, utils, i18n (configureDataTableDefaults, resolveDataTableMessages) |
@benjaminor-dev/quasar-app-extension-datatable/types |
Types + typed helper reexports |
@benjaminor-dev/quasar-app-extension-datatable/main.css |
Styles (registered in quasar.config on install) |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Table without styles | Extension not installed or CSS missing | quasar ext add @benjaminor-dev/datatable; check quasar.config → css |
| Pagination bar missing | Few rows vs first ladder step | Expected when totalRows ≤ minPageSizeStep |
| Narrow cards on mobile | #item slot root not full width |
width: 100% on slot root or dt-data-table-grid-* classes |
TS error Ref<boolean> on :grid |
Ref imported from external package | computed(() => layoutRef.value) in the consumer |
| Pagination texts in English | Quasar language not set or boot locale missing |
Set framework.lang in quasar.config or configureDataTableDefaults({ locale: 'es' }) in boot |
| Defaults boot missing after remove | Partial uninstall or manual delete | quasar ext add @benjaminor-dev/datatable again |
MIT © Benjamín Olvera R.