Vue 实现 AG Grid 自定义单元格编辑(cellEditor)

AG Grid 提供了下面6种cellEditor:

  • 文本,input agTextCellEditor
  • 大文本, textarea agLargeTextCellEditor
  • 单选,select agSelectCellEditor
  • 富文本单选 agRichSelectCellEditor(社区版不提供,需要企业版)
  • 日期选择 agDateCellEditoragDateStringCellEditor
  • 复选框,checkbox agCheckboxCellEditor

但是我们需其他类型的可编辑的单元格的话,就需要我们自定义了。 我这里以自定义一个多选单元格编辑组件来实践一下 AG Grid 的自定义单元格编辑,多选的是使用Ant Design的多选组件

自定义CellEditor

就是单元格在编辑状态使用的组件 agAntdMultiSelectCellEditor.vue

<script setup lang="ts">
import { onMounted, onBeforeUnmount, nextTick, ref } from 'vue';

const props = defineProps<{
  params: any
}>()

const multiSelectRef = ref<any>(null);

const value = ref<string[]>([]);
const options = ref<any[]>([])

const getValue = () => {
  return value.value
}

const initValue = () => {
  value.value = props.params.value;
  const labelMap = props.params.colDef.refData || {};
  options.value = props.params.values.map((item: any) => {
    return {
      label: labelMap[item] || item,
      value: item
    }
  })
};

onMounted(() => {
  initValue()
  nextTick(() => {
    multiSelectRef.value.focus()
  })
})

onBeforeUnmount(() => {
})

defineExpose({
  getValue
});
</script>

<template>
  <a-select
    ref="multiSelectRef"
    v-model:value="value"
    mode="multiple"
    size="small"
    style="width: 100%"
    :options="options"
  ></a-select>
</template>

<style scoped>

</style>

自定义Renderer

就是单元格在非编辑状态(展示)使用的组件 agAntdMultiSelectRenderer.vue

<template>
  <template v-for="(item, index) of value" :key="item">
    <span>{{ labelMap[item] || item }}<span v-if="index < value.length - 1">,</span></span>
  </template>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

const value = ref<any[]>([])
const labelMap = ref<any[]>([])

const props = defineProps<{
  params: any
}>()

onMounted(() => {
  value.value = props.params.value
  labelMap.value = props.params.colDef.refData || {};
})

const refresh = (params: { value: string }) => {
}

defineExpose({
  refresh
});
</script>

<style scoped>
</style>

refresh 方法会在数据变动时调用,可以加入一些自定义的逻辑

AG Grid中使用自定义的cellEditor

<template>
  <ag-grid-vue
    :rowData="rowData"
    :columnDefs="colDefs"
  >
  </ag-grid-vue>
</template>
<script lang="ts" setup>
import { onMounted, ref, shallowRef } from 'vue';
import { AgGridVue } from "ag-grid-vue3";
import { 
  AllCommunityModule, 
  ModuleRegistry, 
  type GridApi, 
  type ColDef, 
  type ColGroupDef 
} from 'ag-grid-community';
import agAntdMultiSelectCellEditor from "./agAntdMultiSelectCellEditor.vue";
import agAntdMultiSelectRenderer from "./agAntdMultiSelectRenderer.vue";

// Register all Community features
ModuleRegistry.registerModules([AllCommunityModule]);

const colDefs = ref<(ColDef|ColGroupDef)[]>([
  // 省略其他列配置
  {
    headerName: '用户',
    field: "user_id",
    editable: true,
    cellRenderer: agAntdMultiSelectRenderer,
    cellEditor: agAntdMultiSelectCellEditor,
    cellEditorParams: {
      values: [1, 2, 3],
    },
    refData: {
      1: '张三',
      2: '李四',
      3: '王五',
    },
    width: 150,
  },
  // 省略其他列配置
])

const rowData = ref([]);
</script>

cellEditorParams.value 可以传入编辑的可选项,refData 可以传入单元格value和要显示label的映射对象(Map)。

参考链接