<script setup lang="ts"> import { reactive, onMounted, ref, onUnmounted } from 'vue'; // utils import { uniqueId, findIndex } from 'src/common/utils/index'; // element import CellAction from './CellAction.vue'; import CellFirstCol from './CellFirstCol.vue'; import CustomHeader from './CustomHeader.vue'; // emitter import emitter from '../../eventbus'; // ag-grid import { AgGridVue } from 'ag-grid-vue3'; // the AG Grid Vue Component import 'ag-grid-community/styles/ag-grid.css'; // Core grid CSS, always needed import 'ag-grid-community/styles/ag-theme-alpine.css'; // Optional theme CSS const defaultColDef = { // sortable: true, flex: 1, editable: true, resizable: true, headerComponent: CustomHeader, }; const sexObj = { man: '男', woman: '女', } as any; const gridApi = ref<any>(null); const rowData = reactive({ value: [ { age: 18, name: '张三', sex: 'man', del: null }, { age: 22, name: '李四', sex: 'man', del: null }, { age: 7, name: '王二小', sex: 'woman', del: null }, { age: 48, name: '张东升', sex: 'man', del: null }, ], }); const columnDefs = reactive({ value: [ { headerName: '姓名', field: 'name', checkboxSelection: true, // 设置数据复选框 headerCheckboxSelection: true, // 表头设置复选框 全选/全取消 cellRenderer: CellFirstCol, }, { headerName: '年龄', field: 'age' }, { headerName: '性别', field: 'sex', cellEditor: 'agSelectCellEditor', // 编辑时显示下拉列表 cellEditorParams: { values: Object.keys(sexObj), }, valueFormatter: (params: any) => { return sexObj[params.value]; }, }, { headerName: '操作', field: 'del', width: 100, pinned: 'right', editable: false, cellRenderer: CellAction, }, ], }); const gridOptions = reactive({ animateRows: true, rowSelection: 'multiple', // multiple 多选 single 单选 defaultColDef, columnDefs: columnDefs.value, rowData: rowData.value, onGridReady: (params: any) => { gridApi.value = params.api; }, // onCellClicked: (event: any) => { // console.log('单击单元格', event); // }, }); onMounted(() => { onEmitterListener(); }); onUnmounted(() => { emitter.all.clear(); }); // 事件监听 function onEmitterListener() { emitter.on('delRow', (data: any) => { delRow(data); }); emitter.on('delCol', (data: any) => { delCol(data); }); emitter.on('upDataHeader', (data: any) => { upDataHeader(data); }); } // 取消选择行 function deselectRows() { gridApi.value.deselectAll(); } // 获取选择行 function getSelectedRows() { let res = gridApi.value.getSelectedRows(); console.log('获取选择行 ==', res); } // 添加行 function addRow() { let columnKeys = columnDefs.value.map((item: any) => { return item.field; }); let obj = {} as any; columnKeys.map((item: any) => { obj[item] = null; }); rowData.value.push(obj); gridApi.value.setRowData(rowData.value); } // 删除行 function delRow(data: any) { rowData.value.splice(data.rowIndex, 1); gridApi.value.setRowData(rowData.value); } // 添加列 function addCol() { let uniId = uniqueId('row_'); // 修改行 rowData.value.map((item: any) => { item[uniId] = null; }); gridApi.value.setRowData(rowData.value); // 修改列 let obj = { headerName: uniId, field: uniId, } as any; let index = columnDefs.value.length - 1; columnDefs.value.splice(index, 0, obj); gridApi.value.setColumnDefs(columnDefs.value); // 自适应 gridApi.value.sizeColumnsToFit(); } // 删除列 function delCol(data: any) { const key = data.column.colId; const index = findIndex(columnDefs.value, ['field', key]); // 修改列 columnDefs.value.splice(index, 1); gridApi.value.setColumnDefs(columnDefs.value); // 修改行 rowData.value.map((item: any) => { delete item[key]; }); gridApi.value.setRowData(rowData.value); // 自适应 gridApi.value.sizeColumnsToFit(); } // 修改列标题 function upDataHeader(data: any) { const index = findIndex(columnDefs.value, ['field', data.data.column.colId]); columnDefs.value[index].headerName = data.value; gridApi.value.setColumnDefs(columnDefs.value); gridApi.value.sizeColumnsToFit(); } </script> <template> <div> <div class="q-gutter-sm"> <q-btn label="取消选择行" @click="deselectRows" color="primary" /> <q-btn label="获取选择的行" @click="getSelectedRows" color="primary" /> <q-btn label="添加行" @click="addRow" color="deep-orange-4" /> <q-btn label="添加列" @click="addCol" color="deep-orange-4" /> </div> <div class="grid"> <ag-grid-vue class="ag-theme-alpine" style="height: 400px" :grid-options="gridOptions" > </ag-grid-vue> </div> </div> </template> <style lang="scss" scoped> .grid { width: 700px; } </style> <style lang="scss"> .ag-theme-alpine { --ag-alpine-active-color: #78c0a8; --ag-selected-row-background-color: rgba(120, 192, 168, 0.3); --ag-row-hover-color: rgba(120, 192, 168, 0.1); --ag-input-focus-border-color: rgba(120, 192, 168, 0.1); } </style>