---
title: "Column Moving"
framework: vue
version: "36.1.0"
---

# Column Moving

Columns can be moved in the grid in the following ways:

- Dragging the column header with the mouse or through touch.
- Using the [keyboard](#move-via-keyboard) to move focused column headers.
- Using the [grid API](#move-via-api).

## Simple Example

The example below demonstrates simple moving via mouse dragging and the API. The following can be noted:

- Dragging the column headers with the mouse moves the column to the new location.
- The **Medals First** and **Medals Last** buttons call the API `moveColumns(keys, toIndex)` to place the medals columns at the start or at the end respectively.
- The **Country First** button calls the API `moveColumns([key], toIndex)` to place the Country column first.
- The **Swap First Two** button calls the API `moveColumnByIndex(fromIndex, toIndex)` to swap the first two columns.
- Focusing a column header and pressing `⇧ Shift` + `←` / `→` moves the column in that direction.
- The **Print Columns** button calls the API `getAllGridColumns()` to print to the dev console the current column order.

#### Column Moving Simple

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  Column,
  ColumnApiModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ColumnApiModule, ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div style="margin-bottom: 1rem">
        <button v-on:click="onMedalsFirst()">Medals First</button>
        <button v-on:click="onMedalsLast()">Medals Last</button>
        <button v-on:click="onCountryFirst()">Country First</button>
        <button v-on:click="onSwapFirstTwo()">Swap First Two</button>
        <button v-on:click="onPrintColumns()">Print Columns</button>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :suppressDragLeaveHidesColumns="true"
        :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" },
      { field: "country" },
      { field: "year" },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 150,
    });
    const rowData = ref<IOlympicData[]>(null);

    function onMedalsFirst() {
      gridApi.value!.moveColumns(["gold", "silver", "bronze", "total"], 0);
    }
    function onMedalsLast() {
      gridApi.value!.moveColumns(["gold", "silver", "bronze", "total"], 6);
    }
    function onCountryFirst() {
      gridApi.value!.moveColumns(["country"], 0);
    }
    function onSwapFirstTwo() {
      gridApi.value!.moveColumnByIndex(0, 1);
    }
    function onPrintColumns() {
      const cols = gridApi.value!.getAllGridColumns();
      const colToNameFunc = (col: Column, index: number) =>
        index + " = " + col.getId();
      const colNames = cols.map(colToNameFunc).join(", ");
      console.log("columns are: " + colNames);
    }
    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,
      onMedalsFirst,
      onMedalsLast,
      onCountryFirst,
      onSwapFirstTwo,
      onPrintColumns,
    };
  },
});

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

[Live example: Column Moving Simple](https://www.ag-grid.com/examples/column-moving/moving-simple/vue3)

## Move via Keyboard

Column headers can be moved using the keyboard. When a column header is focused, press `⇧ Shift` + `←` / `→` to move the column in that direction. The grid will automatically scroll to keep the moved column visible.

See [Column Header Navigation](https://www.ag-grid.com/vue-data-grid/keyboard-navigation/#column-header-navigation) for a full list of header keyboard interactions.

## Move via API

The grid API methods for moving columns are as follows:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `moveColumns` | `Function` |  |  | Moves columns to `toIndex`. The columns are first removed, then added at the `toIndex` location, thus index locations will change to the right of the column after the removal. |
| `moveColumnByIndex` | `Function` |  |  | Moves the column at `fromIndex` to `toIndex`. The column is first removed, then added at the `toIndex` location, thus index locations will change to the right of the column after the removal. |

## Moving Animation

Column animations happen when you move a column. The default is for animations to be turned on. It is recommended that you leave the column move animations on unless your target platform (browser and hardware) is too slow to manage the animations. To turn OFF column animations, set the grid property `suppressColumnMoveAnimation=true`.

[Video](https://www.ag-grid.com/_astro/column-animation.1Go45y9z.mp4)

The move column animation transitions the column's position only, so when you move a column, it animates to the new position. No other attribute apart from position is animated.

## Suppress Hide on Drag Leave

The grid property `suppressDragLeaveHidesColumns` will stop columns getting hidden if they are dragged outside of the grid. This is handy if the user moves a column outside of the grid by accident while moving a column but doesn't intend to make it hidden.

## Suppress Move When Dragging

By default, the columns are moved while you are dragging them. This effect might not be desirable due to your application design. To prevent this use the `suppressMoveWhenColumnDragging` in the `gridOptions`.

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

this.suppressMoveWhenColumnDragging = true;
```

#### Column Moving with SuppressMoveWhenColumnDragging

```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") {
  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"
      :suppressDragLeaveHidesColumns="true"
      :suppressMoveWhenColumnDragging="true"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<(ColDef | ColGroupDef)[]>([
      {
        headerName: "Athlete Info",
        children: [
          { field: "athlete" },
          { field: "age" },
          { field: "country" },
        ],
      },
      {
        headerName: "Event",
        children: [{ field: "year" }, { field: "date" }, { field: "sport" }],
      },
      {
        headerName: "Medals",
        children: [
          { field: "gold" },
          { field: "silver" },
          { field: "bronze" },
          { field: "total" },
        ],
      },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 150,
    });
    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: Column Moving with SuppressMoveWhenColumnDragging](https://www.ag-grid.com/examples/column-moving/suppress-move-when-dragging/vue3)

## Suppress Movable

The column property `suppressMovable` changes whether the column can be dragged. The column header cannot be dragged by the user to move the columns when `suppressMovable=true`. However the column can be inadvertently moved by placing other columns around it thus only making it practical if all columns have this property.

## Lock Position

The column property `lockPosition` locks columns to one side of the grid. When `lockPosition` is set to `"left"`, `"right"`, or `true` (which is treated as `"left"`), the column will always be locked to that position, cannot be dragged by the user, and cannot be moved out of position by dragging other columns.

## Suppress Movable & Lock Position Example

The example below demonstrates these properties as follows:

- The **Age** column is locked `"left"` as the first column in the scrollable area of the grid. It is not possible to move this column, or have other columns moved over it to impact its position. As a result the **Age** column marks the beginning of the scrollable area regardless of its position within the column definitions.
- The **Total** column is locked `"right"` and likewise its position can not be impacted by moving other columns.
- The **Athlete** column has moving suppressed. It is not possible to move this column, but it is possible to move other columns around it.
- The grid has `suppressDragLeaveHidesColumns` set to `true` so columns dragged outside of the grid are not hidden (normally dragging a column out of the grid will hide the column).
- The `defaultColDef` has `lockPinned` set to `true` so it is not possible for the user to pin any columns.
- The **Age** **Total** and **Athlete** columns have the user provided `locked-col` and `suppress-movable-col` CSS classes applied to them respectively to change the background colour.

#### Column Suppress & Lock

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./style.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([CellStyleModule, ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="wrapper">
      <div class="legend-bar">
        <span class="legend-box locked-col"></span> Position Locked Column &nbsp;&nbsp;&nbsp;&nbsp;
        <span class="legend-box suppress-movable-col"></span> Suppress Movable Column
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :suppressDragLeaveHidesColumns="true"
        :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",
        suppressMovable: true,
        cellClass: "suppress-movable-col",
      },
      { field: "age", lockPosition: "left", cellClass: "locked-col" },
      { field: "country" },
      { field: "year" },
      { field: "total", lockPosition: "right", cellClass: "locked-col" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      lockPinned: true, // Dont allow pinning for this example
    });
    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: Column Suppress & Lock](https://www.ag-grid.com/examples/column-moving/suppress-and-lock/vue3)

## Advanced Locked Position Example

Below is a more real-world example of where locked columns would be used. The first column contains buttons for actions, e.g. 'Delete', 'Buy', 'Sell' etc.

From the example the following can be noted:

- The first column is locked into first position by setting `colDef.lockPosition='left'`. This means it cannot be moved out of place, and other columns cannot be moved around it.
- The first column has the user provided `locked-col` CSS class applied to it to change the background colour.
- The sample application listens for column pinned events. If a column is left-pinned, the locked columns are also left-pinned to keep them at the first position. Right-pinning does not affect the locked columns.
  - Clicking **Pin Athlete Left** will left-pin the Athlete column, which will result in locked columns being pinned.
  - Clicking **Pin Athlete Right** will right-pin the Athlete column, which will not affect the locked columns.
  - Clicking **Un-Pin Athlete** will un-pin the Athlete column, which will result in locked columns being un-pinned (assuming no other columns are left pinned).

#### Advanced Lock

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  ColumnPinnedEvent,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import ControlsCellRenderer from "./controlsCellRendererVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

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

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div class="legend-bar">
        <button v-on:click="onPinAthleteLeft()">Pin Athlete Left</button>
        <button v-on:click="onPinAthleteRight()">Pin Athlete Right</button>
        <button v-on:click="onUnpinAthlete()">Un-Pin Athlete</button>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <span class="locked-col legend-box"></span> Position Locked Column
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :suppressDragLeaveHidesColumns="true"
        :rowData="rowData"
        @column-pinned="onColumnPinned"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    ControlsCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        lockPosition: "left",
        cellRenderer: "ControlsCellRenderer",
        cellClass: "locked-col",
        width: 120,
        suppressNavigable: true,
      },
      { field: "athlete" },
      { field: "age" },
      { field: "country" },
      { field: "year" },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 150,
    });
    const rowData = ref<IOlympicData[]>(null);

    function onColumnPinned(event: ColumnPinnedEvent) {
      const allCols = event.api.getAllGridColumns();
      if (event.pinned !== "right") {
        const allFixedCols = allCols.filter(
          (col) => col.getColDef().lockPosition,
        );
        event.api.setColumnsPinned(allFixedCols, event.pinned);
      }
    }
    function onPinAthleteLeft() {
      gridApi.value!.applyColumnState({
        state: [{ colId: "athlete", pinned: "left" }],
      });
    }
    function onPinAthleteRight() {
      gridApi.value!.applyColumnState({
        state: [{ colId: "athlete", pinned: "right" }],
      });
    }
    function onUnpinAthlete() {
      gridApi.value!.applyColumnState({
        state: [{ colId: "athlete", pinned: 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,
      onColumnPinned,
      onPinAthleteLeft,
      onPinAthleteRight,
      onUnpinAthlete,
    };
  },
});

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

[Live example: Advanced Lock](https://www.ag-grid.com/examples/column-moving/advanced-lock/vue3)

## Lock Visible

When you move columns around it is possible to change their visibility as follows:

- You can hide a column by dragging it outside of the grid.
- You can show a column by dragging it from the [Tool Panel](https://www.ag-grid.com/vue-data-grid/tool-panel/) onto the grid (when the grid option `allowDragFromColumnsToolPanel=true`).

The column property `lockVisible` will stop individual columns from being made visible or hidden via the UI. When `lockVisible=true`, the column will not hide when it is dragged out of the grid, and columns dragged from the tool panel onto the grid will not become visible.

There is a slight overlap with the property `suppressDragLeaveHidesColumns`. When `suppressDragLeaveHidesColumns=true` all columns remain visible if they are dragged outside of the grid. This is a good way to block all columns from hiding as the user reorders the columns via dragging. The `lockVisible` property is at the column level and blocks all UI functions that change a column's visibility.

### Lock Visible Example

The example below shows lock visible. The following can be noted:

- `allowDragFromColumnsToolPanel` is enabled, so that columns can be shown by dragging from the tool panel.
- The columns **Age**, **Gold**, **Silver** and **Bronze** are all locked visible. It is not possible to hide the columns by dragging them out of the grid, and not possible to show the columns by dragging them in from the tool panel.
- If you make a group visible or hidden in the tool panel, the locked columns are not impacted.
- If you drag a group (e.g. the **Athlete** group) out of the grid, all normal columns in the group are removed and all locked columns in the group are left intact.

#### Lock Visible

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./style.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  SideBarDef,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnsToolPanelModule,
  FiltersToolPanelModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  CellStyleModule,
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  FiltersToolPanelModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div class="legend-bar"><span class="legend-box locked-visible"></span> Locked Visible Column</div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :sideBar="sideBar"
        :defaultColDef="defaultColDef"
        :allowDragFromColumnsToolPanel="true"
        :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 | ColGroupDef)[]>([
      {
        headerName: "Athlete",
        children: [
          { field: "athlete", width: 150 },
          { field: "age", lockVisible: true, cellClass: "locked-visible" },
          { field: "country", width: 150 },
          { field: "year" },
          { field: "date" },
          { field: "sport" },
        ],
      },
      {
        headerName: "Medals",
        children: [
          { field: "gold", lockVisible: true, cellClass: "locked-visible" },
          { field: "silver", lockVisible: true, cellClass: "locked-visible" },
          { field: "bronze", lockVisible: true, cellClass: "locked-visible" },
          {
            field: "total",
            lockVisible: true,
            cellClass: "locked-visible",
            hide: true,
          },
        ],
      },
    ]);
    const sideBar = ref<SideBarDef | string | string[] | boolean | null>({
      toolPanels: [
        {
          id: "columns",
          labelDefault: "Columns",
          labelKey: "columns",
          iconKey: "columns",
          toolPanel: "agColumnsToolPanel",
          toolPanelParams: {
            suppressRowGroups: true,
            suppressValues: true,
            suppressPivots: true,
            suppressPivotMode: true,
          },
        },
      ],
    });
    const defaultColDef = ref<ColDef>({
      width: 100,
    });
    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,
      sideBar,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

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

[Live example: Lock Visible](https://www.ag-grid.com/examples/column-moving/lock-visible/vue3)

## Custom Drag and Drop Image

The drag and drop image can be customised via the grid properties `dragAndDropImageComponent` and `dragAndDropImageComponentParams`.

Any valid Vue component can be a drag and drop image component, however it must implement the `IDragAndDropImage` interface:

### IDragAndDropImage

```ts

interface IDragAndDropImage {
  setIcon(iconName: string | null, shake: boolean): void;

  setLabel(label: string): void;

}
```

### Custom Params

On top of the parameters provided by the grid, you can also provide your own parameters. This is useful if you want to allow configuring the component. For example, you might have parts of the grid that you want to highlight with a different colour.

```js
colDef = {
    dragAndDropImageComponent: 'MyDragAndDropImageComponent',
    dragAndDropImageComponentParams : {
        accentColour: 'SlateGray'
    }
}
```

#### Custom Drag and Drop Image

```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,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import CustomDragAndDropImage from "./customDragAndDropImageVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

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

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :dragAndDropImageComponent="dragAndDropImageComponent"
      :dragAndDropImageComponentParams="dragAndDropImageComponentParams"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomDragAndDropImage,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      { field: "country" },
      { field: "year", width: 100 },
      { field: "date" },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
    ]);
    const defaultColDef = ref<ColDef>({
      width: 170,
      filter: true,
    });
    const dragAndDropImageComponent = ref("CustomDragAndDropImage");
    const dragAndDropImageComponentParams = ref({
      accentColour: "SlateGray",
    });
    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,
      dragAndDropImageComponent,
      dragAndDropImageComponentParams,
      rowData,
      onGridReady,
    };
  },
});

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

[Live example: Custom Drag and Drop Image](https://www.ag-grid.com/examples/column-moving/custom-drag-drop-image/vue3)
