美文网首页
[Vue ElementUI] Table可编辑列的一种实现

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

作者: AustinPup | 来源:发表于2022-07-05 17:32 被阅读0次

.1 概述

1.1 功能

  • vue-element table的可编辑列实现,参考NG-ZORRO的demo示例,✨地址
  • 支持Table多列修改,只需一个Row-Data自定义属性self-edit,HTML 代码简洁

1.2 一些坑

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

  • 为实现多列修改,同时不额外引入多个变量,通过一自定义的row[self-edit],在后台服务器拿到table-data时, 遍历所有row,引入该对象,🐑要先做完上述数据初始化后,再赋值给table-data变量🐑,因为table-data变量一旦init后,对象的增加、删除、修改无法被vue2监听到
  • 除了事先init上述方式外,也可以通过使用 this.$set(object, key, value)(vue 无法监听 this.$set 修改原有属性), isEdit(scope) 代码方法 便用到了

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

  • 由于这里关联一个方法,修改了判断变量后,element 并没有生效,这里通过this.$refs.multipleTable.doLayout() 显式触发的,multipleTable是el-table 的 ref标签.

🐪 JS的对象删除

  • 这里尝试通过动态对象解构实现的,✨荐文
  • 对象属性是否存在,isEdit(scope) 代码方法

.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;
      }),
}

相关文章

网友评论

      本文标题:[Vue ElementUI] Table可编辑列的一种实现

      本文链接:https://www.haomeiwen.com/subject/fvvsbrtx.html