---
product: "AG Grid"
title: "Row Sorting"
description: "Sort row data in the Vue Data Grid. Customise row sorting with a custom comparator. Sort by multiple columns and apply post sorting for additional control."
framework: vue
version: "36.2.0"
related:
    - title: "Row Data"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-ids/"
    - title: "Row Numbers"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-numbers/"
    - title: "Row Spanning"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-spanning/"
    - title: "Row Pinning"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-pinning/"
    - title: "Row Height"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-height/"
    - title: "Styling Rows"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-styles/"
    - title: "Row Pagination"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-pagination/"
    - title: "Accessing Rows"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/accessing-data/"
    - title: "Row Dragging"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/row-dragging/"
    - title: "Full Width Rows"
      url: "https://www.ag-grid.com/archive/36.2.0/vue-data-grid/full-width-rows/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Row Sorting

This page describes how to sort row data in the grid and how you can customise that sorting to match your requirements.

## Sorting

Sorting is enabled by default for all columns. You can sort a column by clicking on the column header. To enable / disable sorting per column use the `sortable` column definition attribute.

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    { field: 'name' },
    { field: 'age' },
    // disable sorting by address
    { field: 'address', sortable: false },
];
```

To disable sorting for all columns, set sorting in the [default column definition](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/column-definitions/).

```ts
<ag-grid-vue
    :defaultColDef="defaultColDef"
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

// disable sorting on all columns
this.defaultColDef = {
    sortable: false
};
this.columnDefs = [
    // Override default to enable sorting by name
    { field: 'name', sortable: true },
    { field: 'age' },
    { field: 'address' },
];
```

## Custom Sorting

Custom sorting is provided at a column level by configuring a comparator on the column definition.

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    {
        field: 'age',
        // simple number comparator
        comparator: (valueA, valueB, nodeA, nodeB, isDescending) => valueA - valueB
    },
    {
        field: 'name',
        // simple string comparator
        comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {
            if (valueA == valueB) return 0;
            return (valueA > valueB) ? 1 : -1;
        }
    }
];
```

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `comparator` | `SortComparatorFn \| Partial<Record<SortType, SortComparatorFn>>` |  |  |  |

Example below shows the following:

- The **Athlete** column is sorted descending on load.
- When the **Year** column is not sorted, it shows a custom icon (up/down arrow).
- The **Date** column has strings as the row data, but has a custom comparator so that when you sort this column it sorts as dates, not as strings.

#### Custom Sorting

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./style.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);

function dateComparator(date1: string, date2: string) {
  const date1Number = monthToComparableNumber(date1);
  const date2Number = monthToComparableNumber(date2);
  if (date1Number === null && date2Number === null) {
    return 0;
  }
  if (date1Number === null) {
    return -1;
  }
  if (date2Number === null) {
    return 1;
  }
  return date1Number - date2Number;
}

// eg 29/08/2004 gets converted to 20040829
function monthToComparableNumber(date: string) {
  if (date === undefined || date === null || date.length !== 10) {
    return null;
  }
  const yearNumber = Number.parseInt(date.substring(6, 10));
  const monthNumber = Number.parseInt(date.substring(3, 5));
  const dayNumber = Number.parseInt(date.substring(0, 2));
  return yearNumber * 10000 + monthNumber * 100 + dayNumber;
}

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", sort: "desc" },
      { field: "age", width: 90 },
      { field: "country" },
      { field: "year", width: 120, unSortIcon: true },
      { field: "date", comparator: dateComparator },
      { field: "sport" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data.slice(0, 10));

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Custom Sorting](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/custom-sorting/vue3/)

> **Note**
>
> If you are using a custom column header component see [Custom Components](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/column-headers-components/#custom-component) for how to implement sorting.

## Multi Column Sorting

It is possible to sort by multiple columns. The default action for multiple column sorting is for the user to hold down `⇧ Shift` while clicking the column header. To change the default action to use the `^ Ctrl` key instead set the property `multiSortKey='ctrl'`.

The example below demonstrates the following:

- The grid sorts by **Country** then **Athlete** by default.
- The property `multiSortKey='ctrl'` is set so multiple column sorting is achieved by holding down `^ Ctrl` and selecting multiple columns.

#### Multi Column Sort

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  ColumnState,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ColumnApiModule, ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :multiSortKey="multiSortKey"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      { field: "age", width: 100 },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
    });
    const multiSortKey = ref<"ctrl">("ctrl");
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const defaultSortModel: ColumnState[] = [
        { colId: "country", sort: "asc", sortIndex: 0 },
        { colId: "athlete", sort: "asc", sortIndex: 1 },
      ];
      params.api.applyColumnState({ state: defaultSortModel });

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      multiSortKey,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Multi Column Sort](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/multi-column/vue3/)

> **Note**
>
> You can suppress the multi sorting behaviour by enabling the `suppressMultiSort` option, or force the behaviour without key press by enabling the `alwaysMultiSort` option.

## Sorting Animation

By default rows will animate after sorting. If you wish to suppress this animation set the grid property `animateRows=false`.

## Sorting Order

By default, the sorting order is as follows:

**ascending -> descending -> none**.

In other words, when you click a column that is not sorted, it will sort ascending. The next click will make it sort descending. Another click will remove the sort.

It is possible to override this behaviour by providing your own `sortingOrder` on the `colDef`.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `sortingOrder` | `(SortDirection \| SortDef)[]` |  |  |  |

The example below shows different combinations of sorting orders as follows:

- **Column Athlete:** ascending -> descending
- **Column Age:** descending -> ascending
- **Column Country:** descending -> no sort
- **Column Year:** ascending only
- **Default Columns:** descending -> ascending -> no sort

#### Sorting Order and Animation

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", sortingOrder: ["asc", "desc"] },
      { field: "age", width: 90, sortingOrder: ["desc", "asc"] },
      { field: "country", sortingOrder: ["desc", null] },
      { field: "year", width: 90, sortingOrder: ["asc"] },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      sortingOrder: ["desc", "asc", null],
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Sorting Order and Animation](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/sorting-order-and-animation/vue3/)

## Absolute Sorting

Absolute Sorting enables sorting numeric values based on their magnitude, ignoring their sign. This can be used to rank values by their size ignoring if a value is positive or negative.

In the following example, the column `rankingChange` uses absolute sorting:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    // ... other columns
    {
        field: 'rankingChange',
        sort: { direction: 'asc', type: 'absolute' },
        sortingOrder: [
            { direction: 'asc', type: 'absolute' },
            { direction: 'desc', type: 'absolute' },
            null,
        ],
    },
];
```

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `sort` | `SortDirection \| SortDef` |  |  |  |
| `sortingOrder` | `(SortDirection \| SortDef)[]` |  |  |  |

Including an absolute sort adds **Sort Absolute Ascending** and **Sort Absolute Descending** to the [Column Menu](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/column-menu/#built-in-menu-items) default items. These are additive: the plain **Sort Ascending** and **Sort Descending** items sit alongside them rather than being replaced.

#### Absolute Value Sorting

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { any } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", minWidth: 150 },
      { field: "year", maxWidth: 90 },
      {
        field: "rankingChange",
        sort: { direction: "asc", type: "absolute" },
        sortingOrder: [
          { direction: "asc", type: "absolute" },
          { direction: "desc", type: "absolute" },
          null,
        ],
      },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const rowData = ref<any[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) =>
        (rowData.value = data.map((item) => {
          return {
            ...item,
            rankingChange: Math.round(window.agRandom() * 10) - 5,
          };
        }));

      fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Absolute Value Sorting](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/absolute-sorting/vue3/)

## Sorting API

> **Note**
>
> The sort state can be saved and restored as part of [Grid State](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/grid-state/).

What sorting is applied is controlled via [Column State](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/column-state/). The below examples uses the Column State API to control column sorting.

#### Sorting API

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  ClientSideRowModelModule,
  ColumnApiModule,
]);

let savedSort: any;

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div style="margin-bottom: 1rem">
        <div>
          <button v-on:click="sortByAthleteAsc()">Athlete Ascending</button>
          <button v-on:click="sortByAthleteDesc()">Athlete Descending</button>
          <button v-on:click="sortByCountryThenSport()">Country, then Sport</button>
          <button v-on:click="sortBySportThenCountry()">Sport, then Country</button>
        </div>
        <div style="margin-top: 0.25rem">
          <button v-on:click="clearSort()">Clear Sort</button>
          <button v-on:click="saveSort()">Save Sort</button>
          <button v-on:click="restoreFromSave()">Restore from Save</button>
        </div>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :rowData="rowData"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      { field: "age", width: 90 },
      { field: "country" },
      { field: "sport" },
      { field: "year", width: 90 },
      { field: "date" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const rowData = ref<IOlympicData[]>(null);

    function sortByAthleteAsc() {
      gridApi.value!.applyColumnState({
        state: [{ colId: "athlete", sort: "asc" }],
        defaultState: { sort: null },
      });
    }
    function sortByAthleteDesc() {
      gridApi.value!.applyColumnState({
        state: [{ colId: "athlete", sort: "desc" }],
        defaultState: { sort: null },
      });
    }
    function sortByCountryThenSport() {
      gridApi.value!.applyColumnState({
        state: [
          { colId: "country", sort: "asc", sortIndex: 0 },
          { colId: "sport", sort: "asc", sortIndex: 1 },
        ],
        defaultState: { sort: null },
      });
    }
    function sortBySportThenCountry() {
      gridApi.value!.applyColumnState({
        state: [
          { colId: "country", sort: "asc", sortIndex: 1 },
          { colId: "sport", sort: "asc", sortIndex: 0 },
        ],
        defaultState: { sort: null },
      });
    }
    function clearSort() {
      gridApi.value!.applyColumnState({
        defaultState: { sort: null },
      });
    }
    function saveSort() {
      const colState = gridApi.value!.getColumnState();
      const sortState = colState
        .filter(function (s) {
          return s.sort != null;
        })
        .map(function (s) {
          return { colId: s.colId, sort: s.sort, sortIndex: s.sortIndex };
        });
      savedSort = sortState;
      console.log("saved sort", sortState);
    }
    function restoreFromSave() {
      gridApi.value!.applyColumnState({
        state: savedSort,
        defaultState: { sort: null },
      });
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      rowData,
      onGridReady,
      sortByAthleteAsc,
      sortByAthleteDesc,
      sortByCountryThenSport,
      sortBySportThenCountry,
      clearSort,
      saveSort,
      restoreFromSave,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Sorting API](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/sorting-api/vue3/)

## Locale-specific Sort

By default, sorting is not locale-specific and strings are compared using their Unicode code point order. There is no language awareness and no locale rules are applied. If you need to make your sort locale-specific you can configure this by setting the grid option `accentedSort = true`.

> **Note**
>
> Locale-specific sort is slower than default sort which may be noticeable when sorting a large number of rows.

Toggle the buttons in the following example to see the difference between default sorting and locale-aware sorting. Note that with locale-aware sorting, the order is `a à b c` instead of the default Unicode order of `a b c à`.

#### Locale Aware Sort

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="test-container">
      <div class="test-header">
        <button v-on:click="applyLocale()">Locale-specific Sort</button>
        <button v-on:click="applyDefault()">Default Sort</button>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        class="test-grid"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :accentedSort="true"
        :rowData="rowData"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<ColDef[]>([
      { headerName: "Locale-specific Sort", field: "letter", sort: "asc" },
    ]);
    const rowData = ref<any[] | null>([..."bàac"].map((x) => ({ letter: x })));

    function applyLocale() {
      gridApi.value!.updateGridOptions({
        accentedSort: true,
        columnDefs: [
          { field: "letter", sort: "asc", headerName: "Locale-specific Sort" },
        ],
      });
    }
    function applyDefault() {
      gridApi.value!.updateGridOptions({
        accentedSort: false,
        columnDefs: [
          { field: "letter", sort: "asc", headerName: "Default Sort" },
        ],
      });
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      rowData,
      onGridReady,
      applyLocale,
      applyDefault,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Locale Aware Sort](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/locale-aware-sort/vue3/)

## Post-Sort

It is also possible to perform some post-sorting if you require additional control over the sorted rows.

This is provided via the `postSortRows` grid callback function as shown below:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `postSortRows` | `PostSortRows` |  |  |  |

```ts
<ag-grid-vue
    :postSortRows="postSortRows"
    /* other grid options ... */>
</ag-grid-vue>

this.postSortRows = params => {
    let rowNodes = params.nodes;
    // here we put Ireland rows on top while preserving the sort order
    let nextInsertPos = 0;
    for (let i = 0; i < rowNodes.length; i++) {
        const country = rowNodes[i].data.country;
        if (country === 'Ireland') {
            rowNodes.splice(nextInsertPos, 0, rowNodes.splice(i, 1)[0]);
            nextInsertPos++;
        }
    }
};
```

The following example uses this configuration to perform a post-sort on the rows. The custom function puts rows with Ireland at the top always.

#### Post Sort

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  PostSortRows,
  PostSortRowsParams,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :postSortRows="postSortRows"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      { field: "age", width: 100 },
      { field: "country", sort: "asc" },
      { field: "year" },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
    });
    const postSortRows = ref<PostSortRows>(
      (params: PostSortRowsParams<IOlympicData>) => {
        const rowNodes = params.nodes;
        // here we put Ireland rows on top while preserving the sort order
        let nextInsertPos = 0;
        for (let i = 0; i < rowNodes.length; i++) {
          const country = rowNodes[i].data
            ? rowNodes[i].data!.country
            : undefined;
          if (country === "Ireland") {
            rowNodes.splice(nextInsertPos, 0, rowNodes.splice(i, 1)[0]);
            nextInsertPos++;
          }
        }
      },
    );
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => {
        rowData.value = data;
      };

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      postSortRows,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Post Sort](https://www.ag-grid.com/archive/36.2.0/examples/row-sorting/post-sort/vue3/)
