4

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?

  • Did you treid `headerComponentFramework` instead of `headerComponent` ? – Debug Diva Jul 07 '22 at 05:15
  • @RohìtJíndal yes, it doesn't work and you will get the warning that `headerComponentFramework` is deprecated. You should use `headerComponent` instead –  Jul 07 '22 at 05:17

1 Answers1

2

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.
sungryeol
  • 3,677
  • 7
  • 20
  • thanks for your reply. I think I just had to use `const props = defineProps<{ params: IHeaderParams; }>();` . I know that props.params.name exists, but how can I access the `name` property without the use of any? –  Jul 07 '22 at 08:35
  • I can't pass a generic to `IHeaderParams` –  Jul 07 '22 at 08:36
  • 1
    @baitendbidz I've also added an explanation for type combination & prop typings in Vue3 to use with `IHeaderParams`. I hope you like it. ☺️ – sungryeol Jul 07 '22 at 11:44
  • 1
    it turns out, accessing `.params` is slightly different between Class based API and Vue3 component API. it was pretty confusing for me as well. please notice the difference of these codes when actually using it. the ag-grid document indeed needs to be updated. – sungryeol Jul 07 '22 at 11:48