TablePage.vue 4.97 KB
Newer Older
hucy's avatar
hucy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
<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

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>