TablePage.vue 5.12 KB
<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>