Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass props to custom header component using ag-grid?

I'm using Vue 3 with ag-grid and want to setup a new ColDef like so

const colDef: ColDef = {
  field: 'objectKey',
  headerComponent: ColumnHeader, // my custom component
  headerComponentParams: {
    foo: 'bar'
  },
}

My ColumnHeader component defines its props for now

<script setup lang="ts">
const props = defineProps<{
  foo: string;
}>();
</script>

Running the app gives me the following error

[Vue warn]: Missing required prop: "foo" ...

This is because the whole props are undefined.


For reproduction purposes

Plunker snippet https://plnkr.co/edit/OoOD0I8W5NgYX45u which is based on https://www.ag-grid.com/vue-data-grid/component-header/#example-custom-header-component

You will get the error

Missing required prop: "name" ...


Based on https://github.com/ag-grid/ag-grid-vue-example/issues/14 it should work as expected I think. Does someone know what's wrong or missing?


1 Answers

your document clearly states 1. how to use headerComponent in columnDefs and 2. how parameters are passed down to custom header components.

  1. pass a component name as string, just like mounting an external component with <component />. It receives both component itself and mounted component's name in string. My guess is that AgGridVue also uses <component /> internally.
// main.js
data: function () {
    return {
      rowData: [
        {
          foo: 'bar',
        },
      ],
      columnDefs: [
        {
          field: 'foo',
          headerComponent: 'CustomHeader',
          headerComponentParams: {
            name: 'test',
          },
        },
      ],
    };
  },

When a Vue component is instantiated the grid will make the grid APIs, a number of utility methods as well as the cell and row values available to you via this.params - the interface for what is provided is documented below.

  1. modify ColumnHeader to use this.params instead of props.
// customHeaderVue.js
export default {
  template: `
      <div>
        *{{ name }}*
      </div>
    `,
  computed: {
    name() {
      return this.params.name;
    },
  },
};

working demo: https://plnkr.co/edit/L7X6q3Mr7K0pewO8

edit: ag-grid's IHeaderParams does not support generics. to extend given type without generics, please use these methods.

import type { IHeaderParams } from "ag-grid-community";
// fig 1
// combine with type intersection
type CustomHeaderParams = IHeaderParams & { name: string };

// fig2
// combine with interface extension
interface CustomHeaderParams extends IHeaderParams {
  name: string;
}

here are typed examples of CustomHeader.vue

// fig 1. Vue3 composition API, with <script setup>
<script lang="ts" setup>
import { defineProps, onMounted, ref } from "vue";
import type { IHeaderParams } from "ag-grid-community";
type CustomHeaderParams = IHeaderParams & { name: string };

const props = defineProps<{ params: CustomHeaderParams }>();
const name = ref(props.params.name);
</script>

<template>
  <div>*{{ name }}*</div>
</template>

// ------
// 2. Vue3 options API, without <script setup>
<script lang="ts">
import { defineComponent, type PropType } from "vue";
import type { IHeaderParams } from "ag-grid-community";
type CustomHeaderParams = IHeaderParams & { name: string };
export default defineComponent({
  props: {
    params: {
      type: Object as PropType<CustomHeaderParams>,
    },
  },
  setup(props) {
    return { name: props.params?.name ?? "" };
  },
});
</script>

<template>
  <div>*{{ name }}*</div>
</template>

note: I've suggested using the component's name in columnDefs.headerComponent because the official document says so, and seems fine in the working demo; but it actually depends on the Vue API. I assume it has something to do with Vue internal variable scope.

  • Vue Options API(Class based component): put component name string.
  • Vue Compositions API(Functional component): put the component variable itself.
like image 107
sungryeol Avatar answered Oct 17 '25 10:10

sungryeol



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!