[Vue ElementUI] Table可编辑列的一种实现

2022-07-05  本文已影响0人  AustinPup

.1 概述

1.1 功能

1.2 一些坑

🐪 Vue 不能检测数组和对象的变化

🐪 element-table 的v-show功能失效问题

🐪 JS的对象删除


.2 Html

       <!------ ↓ ↓ table-可编辑列-customer-FCST ID ↓ ↓ ------>
        <el-table-column prop="customer" label="FCST ID" width="120" >
               <template slot-scope="scope">
                  <span :title="getColTitle(scope)" v-show="!isEdit(scope)" class="scspan-width"
                        @dblclick="inEdit(scope)">{{ getColTitle(scope) }}<i class="el-icon-edit"></i></span>

                   <el-input v-model="scope.row['self-edit'][scope.column.property]" v-show="isEdit(scope)"
                        :placeholder="coledit4place(scope)" @blur="coledit4bur(scope)">
                        <i :class="coledit4iconstyle(scope)" slot="suffix" @click="handleIconClick(scope)"> </i>
                    </el-input>
               </template>
          </el-table-column>
      <!------  ↑ ↑ table-可编辑列-customer-FCST ID  ↑ ↑ ------>

这里利用了 vue-插槽 机制自定义列布局, 正常模式的span 和 编辑模式的input两个组件, 用户点击Span块时,进入编辑模式,编辑完后点击图标确认。


.3 CSS

.scspan-width {
  display: -moz-inline-box;
  display: inline-block;
  min-width: 90px;
  min-height: 20px;
  cursor: pointer;
}

.ico-hide {
  display: none;
}

.g-hand {
    cursor: pointer;
}

.4 JS

//============== ↓ ↓ 可编辑table-列 方法集 ↓ ↓  ================================
    //进入编辑模式
    inEdit(scope) {
      console.log("index", scope.$index, scope)
      let row = scope.row
      let label = scope.column.property;

      let editval = row['self-edit'];
      // editval[label] = row[label]
      this.$set(editval, label, row[label])

      this.$refs.multipleTable.doLayout()
    },

    //判断当前是否编辑模式
    isEdit(scope) {
      let row = scope.row;
      let label = scope.column.property;
      let editval = row['self-edit'];
      let isshow = label in editval;

      return isshow;
    },

    //span的内容
    getColTitle(scope) {
      let row = scope.row;
      let label = scope.column.property;
      return row[label];
    },

    //编辑图标的样式,当文本发生变化时便展示
    coledit4iconstyle(scope) {
      let row = scope.row;
      let label = scope.column.property;

      let edval = row['self-edit'][label];
      let oldval = row[label]
      if (edval != oldval) {
        return "el-icon-edit el-input__icon g-hand ";
      }

      return "el-icon-edit el-input__icon g-hand ico-hide";
    },

    //编辑input的占位文本
    coledit4place(scope) {
      let row = scope.row;
      let label = scope.column.property;
      return row['self-edit'][label];
    },

    //编辑input失去焦点时,不修改,退出编辑模式,恢复正常展示
    coledit4bur(scope) {
      console.log("失去焦点", scope)
      setTimeout(() => {
        let row = scope.row;
        let label = scope.column.property;

        console.log("blur的self", JSON.stringify(row['self-edit']))
        if (!(label in row['self-edit'])) {
          console.log("已不再,无需处理")
          return;
        }

        let { [label]: name, ...rest } = row['self-edit']
        this.$set(scope.row, 'self-edit', rest)
        this.$refs.multipleTable.doLayout()
      }, 200);
    },


    //编辑图标点击修改,这里需调用backend-api
    handleIconClick(scope) {
      console.log("点击图标", scope)
      let row = scope.row;
      let label = scope.column.property;
      //修改值
      let edval = row['self-edit'][label];
      row[label] = edval

      this.net4updateCol(scope)
      //动态解构对象,删除对象特定属性,相比delete 性能更高
      let { [label]: name, ...rest } = row['self-edit']
      this.$set(scope.row, 'self-edit', rest)
      this.$refs.multipleTable.doLayout()
    },

    //============== ↑ ↑ 可编辑table-列 方法集 ↑ ↑  ================================
   
   // 表数据初始化的配置,添加一个自定义对象 self-edit
   loadItemData() {
      this.listLoading = true;
      getInitCustomerDemand().then(response => {
        let ct = response.payload.page.records
        this.mappingMonth = response.payload.mappingMonth

        for (let row of ct) {
          row['self-edit'] = {};
        }

        //tabledata的初始化位置注意,一定要在自定义的新属性添加进去后,再初始化;
        //不然Vue 不能检测数组和对象的变化
        this.tableData = ct;
      }),
}

上一篇 下一篇

猜你喜欢

热点阅读