使用umy-ui的大数据量编辑表格(ux-grid)获取修改列进行提交

背景

最近的一个新项目需要用到大数据表格编辑,苦于在elementUI中的table控件不支持虚拟滚动和对表格内编辑不友好,我们只能寻求其它支持大数据展示的控件库,最后选用了umy-ui进行前端大数据表格开发。而最近在使用表格编辑时候看到了有获取编辑行的方法(getUpdateRecords),但由于我们可能会多个人同时编辑一行但是不同列的原因,不允许直接把当前行的结果进行提交,然而我没有在官方文档找到获取已编辑列的方法,于是就按自己的想法来实现该需求。因为有些人仅需要实现方案,所以下面优先给出解决方案再说明我的解决思路以供参考。


展示效果

  1. 页面打开样式,编辑前
    使用umy-ui的大数据量编辑表格(ux-grid)获取修改列进行提交_第1张图片

  2. 编辑4个单元格
    使用umy-ui的大数据量编辑表格(ux-grid)获取修改列进行提交_第2张图片

  3. 提交输出
    使用umy-ui的大数据量编辑表格(ux-grid)获取修改列进行提交_第3张图片


解决方案

<template>
  <div>
    <el-row>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-finished"
          size="mini"
          @click="handleSave"
        >保存改动el-button>
      el-col>
    el-row>
    <ux-grid ref="table" use-virtual border height="430px"
        :edit-config="{trigger: 'click', mode: 'cell'}"
        big-data-checkbox show-overflow="title"
        keep-source @edit-closed="editClosed">
      <ux-table-column type="checkbox" width="55" align="center" />
      <ux-table-column type="index" width="60" title="序号" align="center" />
      <template v-for="item in columns">
        <ux-table-column
            :key="item.field" :field="item.field"
            :title="item.title" align="center" width="100"
            edit-render>
          
          <template v-slot:edit="scope">
            <el-input v-model="scope.row['field']">el-input>
          template>
        ux-table-column>
      template>
    ux-grid>
  div>
template>

<script>
  export default {
    name: "Test",
    created() {
      // 在组件打开时就进行数据查询
      this.getList();
    },
    data() {
      return {
        // 编辑过的单元格, key为ID值, value为列名称对象, 避免提交修改一整行
        editColumns: {},
        // 表格的列
        columns: [{
            field: 'field1',
            title: '字段1'
          },{
            field: 'field2',
            title: '字段2'
          },{
            field: 'field3',
            title: '字段3'
          },{
            field: 'field4',
            title: '字段4'
          },{
            field: 'field5',
            title: '字段5'
          }
        ]
      }
    },
    methods: {
      /** 查询数据 */
      getList() {
        // 每次重新查询时, 将数据编辑记录清空
        this.editColumns = {};
        this.$nextTick(() => {
          let dataList = [];
          for (let i = 0; i < 500; i++) {
            dataList.push({
              id: i,
              field1: `field1_${i}`,
              field2: `field2_${i}`,
              field3: `field3_${i}`,
              field4: `field4_${i}`,
              field5: `field5_${i}`,
            })
          }
          this.$refs.table.reloadData(dataList);
          // 大数据测试表格数据, 此变量不写入data()
          this.bigDataDemoList = dataList;
          // 备份原数据, 避免修改后无法对比是否更改, 此变量不写入data()
          this.sourceTableData = JSON.parse(JSON.stringify(this.bigDataDemoList));
        })
      },
      /** 保存数据 */
      handleSave() {
        let editRows = this.$refs.table.getUpdateRecords();
        if (editRows.length == 0) {
          this.$modal.msgWarning("没有修改的行");
          return;
        }
        // 遍历更新行, 只将编辑的列进行提交
        let submitEditDatas = [];
        editRows.forEach(row => {
          let submitEditData = {};
          submitEditData.id = row.id;
          // 只将编辑的列进行提交
          for (let key in this.editColumns[row.id]) {
            submitEditData[key] = this.editColumns[row.id][key]
          }
          submitEditDatas.push(submitEditData);
        });
        console.log("提交的数据", submitEditDatas);
        this.$message.success("修改成功")
      },
      /** 表格编辑完毕时*/
      editClosed(event) {
        let row = event.row;
        let prop = event.column.property;
        // 记录下已变更的字段
        let sourceTableRowData = this.sourceTableData.find(item => item.id === row.id);
        if (row[prop] !== sourceTableRowData[prop]) {
          if (this.editColumns[row.id] == null) {
            this.editColumns[row.id] = {};
          }
          this.editColumns[row.id][prop] = row[prop];
          return;
        }
        // 如果还原了列值, 则将对象中的key删除, 避免在提交时仍遍历了该属性
        let isRevertFieldVal = this.editColumns[row.id] != null && this.editColumns[row.id].hasOwnProperty(prop);
        if (isRevertFieldVal) {
          delete this.editColumns[row.id][prop];
        }
      }
    }
  }
script>

解决问题的思路

  • 通过查找官方文档获取编辑列的方法,但是找不着,只能获取编辑行getUpdateRecords,放弃
  • 使用编辑激活事件(edit-actived)全局变量记录下当前单元格的值,然后在编辑完成事件(edit-closed)记录的变化对象进行比较,如果不同的就记录该列是产生变化的,在submit中取编辑行并遍历列改变量取到修改的列进行提交,但是存在的问题是如果原始值是a,我把单元格的值改成b后再改成a依然会记录是已修改的值, 放弃
  • 在表格数据查出来后将数据克隆到全局变量中,这样我们能在edit-closed与原始值做比较(要是能直接通过表格获取原始值就好了- -||,因为启用了keep-source是会克隆原始值的,但是api中并未提供获取方法,只能自己又克隆一遍),在每次编辑完成事件记录下改变的字段值,如果用户将值修改为与原始值相同的时候,清楚记录值。
  • PS:如果有找到api中有提供修改列,可以留个言告知一下哈

参考链接

umy-ui官方文档

你可能感兴趣的:(vue,elementui,javascript,umy-ui)