美文网首页
[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