The Client-Side Row Model can display skeleton rows instead of the loading overlay while row data is loading.
import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
LoadingRowsOptions,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
ModuleRegistry.registerModules([ClientSideRowModelModule]);
interface IAthlete {
athlete: string;
country: string;
sport: string;
year: number;
gold: number;
silver: number;
bronze: number;
}
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<div class="example-wrapper">
<div class="example-header">
<label>
<span>loading:</span>
<input type="checkbox" id="loading-toggle" checked="" v-on:change="onLoadingToggled()">
</label>
<label>
<span>loadingRows.rowCount:</span>
<input type="number" id="row-count" min="1" max="50" value="10" v-on:change="onRowCountChanged()">
</label>
</div>
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:rowData="rowData"
:loading="true"
:loadingRows="loadingRows"
:columnDefs="columnDefs"></ag-grid-vue>
</div>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup(props) {
const gridApi = shallowRef<GridApi<IAthlete> | null>(null);
const rowData = ref<IAthlete[] | null>([
{
athlete: "Michael Phelps",
country: "United States",
sport: "Swimming",
year: 2008,
gold: 8,
silver: 0,
bronze: 0,
},
{
athlete: "Natalie Coughlin",
country: "United States",
sport: "Swimming",
year: 2008,
gold: 1,
silver: 2,
bronze: 3,
},
{
athlete: "Aleksey Nemov",
country: "Russia",
sport: "Gymnastics",
year: 2000,
gold: 2,
silver: 1,
bronze: 3,
},
{
athlete: "Alicia Coutts",
country: "Australia",
sport: "Swimming",
year: 2012,
gold: 1,
silver: 3,
bronze: 1,
},
{
athlete: "Missy Franklin",
country: "United States",
sport: "Swimming",
year: 2012,
gold: 4,
silver: 0,
bronze: 1,
},
{
athlete: "Ryan Lochte",
country: "United States",
sport: "Swimming",
year: 2012,
gold: 2,
silver: 2,
bronze: 1,
},
{
athlete: "Chris Hoy",
country: "Great Britain",
sport: "Cycling",
year: 2008,
gold: 3,
silver: 0,
bronze: 0,
},
{
athlete: "Ian Thorpe",
country: "Australia",
sport: "Swimming",
year: 2000,
gold: 3,
silver: 2,
bronze: 0,
},
]);
const loadingRows = ref<boolean | LoadingRowsOptions>({ rowCount: 10 });
const columnDefs = ref<ColDef[]>([
{ field: "athlete" },
{ field: "country" },
{ field: "sport" },
{ field: "year" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
]);
function onLoadingToggled() {
const loading =
document.querySelector<HTMLInputElement>("#loading-toggle")!.checked;
gridApi.value.setGridOption("loading", loading);
}
function onRowCountChanged() {
const rowCount =
document.querySelector<HTMLInputElement>("#row-count")!.valueAsNumber;
if (!Number.isInteger(rowCount) || rowCount < 1) {
return;
}
gridApi.value.setGridOption("loadingRows", { rowCount });
}
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
};
return {
gridApi,
rowData,
loadingRows,
columnDefs,
onGridReady,
onLoadingToggled,
onRowCountChanged,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.example-header {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 10px;
}
.example-header label {
display: flex;
align-items: center;
gap: 6px;
}
.example-header input[type='number'] {
width: 60px;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
For loading rows managed by a server-side datasource, see Server-Side Row Model Loading Rows.
Enabling Loading Rows Copy Link
Set loadingRows=true to use skeleton rows when loading=true. Ten rows are displayed by default. Alternatively, provide LoadingRowsOptions with rowCount to configure the number displayed.
<ag-grid-vue
:loading="loading"
:loadingRows="loadingRows"
/* other grid options ... */>
</ag-grid-vue>
this.loading = true;
this.loadingRows = {
rowCount: 10,
};Show or hide the loading UI. true: the loading overlay is shown, or skeleton rows if loadingRows is enabled (Client-Side Row Model only). false: the loading UI is hidden. undefined: the grid will automatically show the loading overlay until rowData and columnDefs are provided. (Client Side Row Model only) |
Display skeleton rows instead of the loading overlay when loading=true (Client-Side Row Model only).
Set to true to display ten rows, or provide options to configure the row count.
This option does not start loading; set loading=true to show the skeleton rows. |
Loading rows are visual placeholders and are not included in Client-Side Row Model operations such as sorting, filtering, grouping or selection. When loading finishes, set loading=false to display the row data.
Both options can be updated at runtime. Update loadingRows to change the row count while loading, or set it to false to switch back to the overlay without ending the loading state.
Custom Loading Cells Copy Link
Set loadingCellRenderer and loadingCellRendererParams on a column definition to customise that column, or on defaultColDef to customise every loading cell. See Loading Cell Component for component interfaces, parameters and dynamic component selection.
The following example uses a custom loading component for the Athlete column while the other columns retain the default skeleton effect.
import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
LoadingRowsOptions,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
import CustomLoadingCellRenderer from "./customLoadingCellRendererVue";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
ModuleRegistry.registerModules([ClientSideRowModelModule]);
interface IAthlete {
athlete: string;
country: string;
sport: string;
year: number;
gold: number;
silver: number;
bronze: number;
}
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<div class="example-wrapper">
<div class="example-header">
<label>
<span>loading:</span>
<input type="checkbox" id="loading-toggle" checked="" v-on:change="onLoadingToggled()">
</label>
</div>
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:rowData="rowData"
:loading="true"
:loadingRows="loadingRows"
:columnDefs="columnDefs"></ag-grid-vue>
</div>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
CustomLoadingCellRenderer,
},
setup(props) {
const gridApi = shallowRef<GridApi<IAthlete> | null>(null);
const rowData = ref<IAthlete[] | null>([
{
athlete: "Michael Phelps",
country: "United States",
sport: "Swimming",
year: 2008,
gold: 8,
silver: 0,
bronze: 0,
},
{
athlete: "Natalie Coughlin",
country: "United States",
sport: "Swimming",
year: 2008,
gold: 1,
silver: 2,
bronze: 3,
},
{
athlete: "Aleksey Nemov",
country: "Russia",
sport: "Gymnastics",
year: 2000,
gold: 2,
silver: 1,
bronze: 3,
},
{
athlete: "Alicia Coutts",
country: "Australia",
sport: "Swimming",
year: 2012,
gold: 1,
silver: 3,
bronze: 1,
},
{
athlete: "Missy Franklin",
country: "United States",
sport: "Swimming",
year: 2012,
gold: 4,
silver: 0,
bronze: 1,
},
{
athlete: "Ryan Lochte",
country: "United States",
sport: "Swimming",
year: 2012,
gold: 2,
silver: 2,
bronze: 1,
},
{
athlete: "Chris Hoy",
country: "Great Britain",
sport: "Cycling",
year: 2008,
gold: 3,
silver: 0,
bronze: 0,
},
{
athlete: "Ian Thorpe",
country: "Australia",
sport: "Swimming",
year: 2000,
gold: 3,
silver: 2,
bronze: 0,
},
]);
const loadingRows = ref<boolean | LoadingRowsOptions>({ rowCount: 10 });
const columnDefs = ref<ColDef[]>([
{
field: "athlete",
loadingCellRenderer: "CustomLoadingCellRenderer",
loadingCellRendererParams: {
loadingMessage: "Loading athletes...",
},
},
{ field: "country" },
{ field: "sport" },
{ field: "year" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
]);
function onLoadingToggled() {
const loading =
document.querySelector<HTMLInputElement>("#loading-toggle")!.checked;
gridApi.value.setGridOption("loading", loading);
}
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
};
return {
gridApi,
rowData,
loadingRows,
columnDefs,
onGridReady,
onLoadingToggled,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.example-header {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 10px;
}
.example-header label {
display: flex;
align-items: center;
gap: 6px;
}
.example-header input[type='number'] {
width: 60px;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
export default {
template: `
<div class="ag-custom-loading-cell">
<i class="fas fa-spinner fa-pulse"></i> <span>{{ params.loadingMessage }}</span>
</div>
`,
};