当前位置 : 主页 > 网络编程 > JavaScript >

Element Table行的动态合并及数据编辑示例

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 正文 思路 1:第二列和第三列第四列根据名称进行合并 2:可以动态编辑第三列和第四列解决 3:第一列的数据是根据第三列相加得来的 4:弹出个输入框 完整代码 正文 先描述一下
目录
  • 正文
  • 思路
    • 1:第二列和第三列第四列根据名称进行合并
    • 2:可以动态编辑第三列和第四列解决
    • 3:第一列的数据是根据第三列相加得来的
    • 4:弹出个输入框
  • 完整代码

    正文

    先描述一下需求,看下图

    1:动态合并行,如图所示,第一列全部合并,第二列和第三列第四列根据名称进行合并

    2:可以动态编辑第三列和第四列,并且只能编辑属于此合并行的第三列和第四列,比如第一个编辑按钮点击后,只有前三行可以编辑

    3:第一列的数据是根据第三列相加得来的

    4:点击快捷填写,可以快速填写第三列和第四列

    思路

    1:第二列和第三列第四列根据名称进行合并

    后台根据名称进行排序,前台通过循环解析名称来知道哪一行需要合并,这个从网上找了一个自己改了下。

     第一列特殊情况根据上面的思路做简单修改

    element代码: span-method="cellMerge"

    <el-table
          border
          :data="tableData3"
          height="100%"
          width="100%"
          :cell-style="cellStyle"
          :row-style="getRowClass"
          :header-row-style="getRowClass"
          :header-cell-style="getRowClass"
          :span-method="cellMerge"
        > 

    vue代码:

    //合并单元格,此方法需要后台进行名字进行排序
        cellMerge({ row, column, rowIndex, columnIndex }) {
          let length = this.tableData3.length;
          //第0列比较特殊,单独合并
          if (columnIndex === 0) {
            const _row = this.spanArrOne[rowIndex];
            const _col = _row > 0 ? 1 : 0;
            return {
              rowspan: _row,
              colspan: _col
            };
          }
          //1 2 5列进行合并
          if (columnIndex === 1 || columnIndex === 2 || columnIndex === 5) {
            const _row = this.spanArr[rowIndex];
            const _col = _row > 0 ? 1 : 0;
            return {
              rowspan: _row,
              colspan: _col
            };
          }
        },
        //1 2  5列合并的数据
        getSpanArr(data) {
          for (var i = 0; i < data.length; i++) {
            if (i === 0) {
              this.spanArr.push(1);
              this.pos = 0;
            } else {
              // 判断当前元素与上一个元素是否相同
              if (data[i].name === data[i - 1].name) {
                this.spanArr[this.pos] += 1; //需要合并的行数
                this.spanArr.push(0); //新增被合并的行
              } else {
                this.spanArr.push(1);
                this.pos = i; //新的需要合并的第几行数
              }
            }
          }
        },
        //0列合并的数据
        getSpanArrOne(data) {
          for (var i = 0; i < data.length; i++) {
            if (i === 0) {
              this.spanArrOne.push(1);
              this.posOne = 0;
            } else {
              this.spanArrOne[this.posOne] += 1; //需要合并的行数
              this.spanArrOne.push(0); //新增被合并的行
            }
          }
          console.log(this.spanArrOne, " this.spanArrOne");
        },

    2:可以动态编辑第三列和第四列解决

       添加template模块,里面添加input输入框和span标签,通过属性进行控制,我是通过取出后台数据,遍历后添加了自定义属性editing来控制的,为了只能编辑通过名称合并的第三列和第四列,我添加了属性flagNum,名字相同的行flagNum一样,我这边打印出来的是 0-2行是0  3到5行是3  6到9行是6以此类推,可以发现其规律就是第一个开头的行,当你点击第一个编辑按钮的时候,传的index就是0,所以根据flagNum匹配0-2行可以编辑,下面的是一样的逻辑

    element代码;

     <el-table-column prop="value1" label="XXX" min-width="15%" align="center">
            <template slot-scope="scope">
              <template v-if="scope.row.editing">
                <el-input class="edit-input" v-model="scope.row.value1"></el-input>
              </template>
              <span v-else>{{ scope.row.value1 }}</span>
            </template>
          </el-table-column>

    vue代码:

    //判断可编辑作用域 用到的数据spanArr4Edit
        getSpanArr4Edit(data) {
          let ctx = this;
          var flagNum = 0;
          for (var i = 0; i < data.length; i++) {
            //首先不能编辑
            ctx.$set(data[i], "editing", false);
            if (i === 0) {
              ctx.spanArr4Edit.push(flagNum);
            } else {
              // 判断当前元素与上一个元素是否相同
              if (data[i].name === data[i - 1].name) {
                ctx.spanArr4Edit.push(flagNum); //还是同一个记录
              } else {
                ctx.spanArr4Edit.push(i);
                flagNum = i;
              }
            }
            //与编辑相对应
            ctx.$set(data[i], "flagNum", flagNum);
          }
          //最终赋值
          ctx.tableData3 = data;
          console.log(ctx.spanArr4Edit, "this.spanArr4Edit");
        },
    handleEdit(index, row) {
          let ctx = this;
          this.setEditFlag(index, 1);
          console.log(index);
        },
    /编辑输入框显示与隐藏0 隐藏 1显示
        setEditFlag: function(index, flag) {
          let ctx = this;
          let datalength = ctx.tableData3.length;
          let flagNum = ctx.spanArr4Edit[index];
          for (let i = 0; i < datalength; i++) {
            if (flag == 1) {
              if (flagNum === ctx.tableData3[i].flagNum) {
                //循环遍历改变可编辑的标记
                this.$set(ctx.tableData3[i], "editing", true);
              }
            } else {
              //循环遍历改变可编辑的标记
              this.$set(ctx.tableData3[i], "editing", false);
            }
          }
        }

    3:第一列的数据是根据第三列相加得来的

    可以用监听器深度监听后台传过来的数据

    代码:

     watch: {
        tableData3: {
          handler(newValue, oldValue) {
            let ctx = this;
            let length = oldValue.length;
            var num = 0;
            if (length > 0) {
              for (let i = 0; i < length; i++) {
                //取出编辑后的对象数据
                num = Number(num) + Number(ctx.tableData3[i].value1);
              }
              if (num != 0) {
                 //赋值对象数据
                ctx.tableData3[0].all = num;
              } else {
                ctx.tableData3[0].all = "";
              }
            }
          },
          deep: true //深度监听对象里面的属性
        }
      },

    4:弹出个输入框

    此逻辑比较简单,就是弹出个输入框,点击确认把值带到这个页面进行填写

    直接上代码:

      //快捷填写保存
        addSubmit: function() {
          let ctx = this;
          //赋值数据,取出哪一行需要进行赋值
          let idx = this.quickFlag;
          let datalength = ctx.tableData3.length;
          //每次快捷填写某一个区域,所以此变量在此定义
          var initFlag = 0;
          for (let i = 0; i < datalength; i++) {
            if (idx === ctx.tableData3[i].flagNum) {
              if (initFlag == 0) {
                //value1 只赋值一次就行
                this.$set(ctx.tableData3[i], "value1", this.addform.w);
              }
              initFlag++;
              this.$set(ctx.tableData3[i], "value2", this.addform.q);
            }
          }
          this.dialogQuick = false;
          ctx.$message.success("操作成功");
          console.log(this.addform, "this.addform");
        },

    -----------------------------------分割线------------------------------------------------

    完整代码

    <template>
      <div class="waterApplyTable">
        <el-table
          border
          :data="tableData3"
          height="100%"
          width="100%"
          :cell-style="cellStyle"
          :row-style="getRowClass"
          :header-row-style="getRowClass"
          :header-cell-style="getRowClass"
          :span-method="cellMerge"
        > 
        <el-table-column  prop="title"  :label="title" align="center">
          <el-table-column  prop="all" label="xx" min-width="20%">
            <template slot-scope="scope">
              <span>{{ scope.row.all }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="name" label="xx" min-width="15%" align="center" show-overflow-tooltip></el-table-column>
          <el-table-column prop="value1" label="xx" min-width="15%" align="center">
            <template slot-scope="scope">
              <template v-if="scope.row.editing">
                <el-input class="edit-input" v-model="scope.row.value1"></el-input>
              </template>
              <span v-else>{{ scope.row.value1 }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="value2" label="xx" min-width="15%" align="center">
            <template slot-scope="scope">
              <template v-if="scope.row.editing">
                <el-input class="edit-input" v-model="scope.row.value2"></el-input>
              </template>
              <span v-else>{{ scope.row.value2 }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="value3" label="xx" min-width="15%" align="center"></el-table-column>
          <el-table-column prop="editing" label="操作" min-width="20%" align="center">
            <template slot-scope="scope">
              <el-button
                type="primary"
                v-if="!scope.row.editing"
                @click.native="handleEdit(scope.$index, scope.row)"
              >编辑</el-button>
              <el-button type="primary" v-else @click.native="savemodify(scope.$index, scope.row)">保存</el-button>
              <el-button type="primary" @click.native="clickTodo(scope.$index, scope.row)">快捷填写</el-button>
            </template>
          </el-table-column>
        </el-table-column>
        </el-table>
        <el-dialog
          class="dialog"
          :visible="dialogQuick"
           top="15vh"
          @close="dialogQuickClose"
          width="20%"
          title="快捷填写"
          :append-to-body="true"
        >
          <el-form :model="addform" class="demo-form-inline">
            <el-form-item label="x">
              <el-input v-model.trim="addform.w"></el-input>
            </el-form-item>
            <el-form-item label="xx">
              <el-input v-model.trim="addform.q"></el-input>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click.native="addSubmit">确定</el-button>
          </div>
        </el-dialog>
      </div>
    </template>
    <script>
    export default {
      name: "waterApplyTable",
      props: {
        total: {
          type: Number,
          default: 100
        }
      },
      data() {
        return {
          rules: {},
          page: 1,
          pageSize: 20,
          pageCount: 10,
          formInline: {
            area: "青岛市",
            year: "2018-2019"
          },
          tableData3: [],
          dialogQuick: false,
          addform: {},
          spanArr: [],
          pos: "",
          spanArrOne: [],
          posOne: "",
          spanArr4Edit: [],
          pos4Edit: "",
          //快捷填写flag,记录哪一行数据的快捷填写
          quickFlag: "",
          title:'我是表头',
        };
      },
      watch: {
        tableData3: {
          handler(newValue, oldValue) {
            let ctx = this;
            let length = oldValue.length;
            var num = 0;
            if (length > 0) {
              for (let i = 0; i < length; i++) {
                num = Number(num) + Number(ctx.tableData3[i].value1);
              }
              if (num != 0) {
                ctx.tableData3[0].all = num;
              } else {
                ctx.tableData3[0].all = "";
              }
            }
          },
          //immediate: true,
          deep: true //深度监听对象里面的属性
        }
      },
      created() {
        this.getData();
      },
      mounted() {
        // this.getData();
      },
      methods: {
        getData() {
          this.getTableDataList();
        },
        // 列表, 
        getTableDataList() {
          let ctx = this;
          // ctx.$api
          //   .getTableDataList()
          //   .then(res => {
          //     ctx.total = res.totalRows;
          //     ctx.pageCount = ctx.total / ctx.pageSize + 1;
          //     ctx.tableData = res.rows;
          //   })
          //   .catch(() => {
          //   });
          let _data = [
            {
              all: "",
              name: "名字1",
              value1: "",
              value2: "",
              value3: "2017年-10月"
            },
            {
              all: "",
              name: "名字1",
              value1: "",
              value2: "",
              value3: "2017年-11月"
            },
            {
              all: "",
              name: "名字1",
              value1: "",
              value2: "",
              value3: "2017年-12月"
            },
            {
              all: "",
              name: "名字2",
              value1: "",
              value2: "",
              value3: "2017年-10月"
            },
            {
              all: "",
              name: "名字2",
              value1: "",
              value2: "",
              value3: "2017年-11月"
            },
            {
              all: "",
              name: "名字2",
              value1: "",
              value2: "",
              value3: "2017年-12月"
            },
            {
              all: "",
              name: "名字3",
              value1: "",
              value2: "",
              value3: "2017年-10月"
            },
            {
              all: "",
              name: "名字3",
              value1: "",
              value2: "",
              value3: "2017年-11月"
            },
            {
              all: "",
              name: "名字3",
              value1: "",
              value2: "",
              value3: "2017年-12月"
            },
            {
              all: "",
              name: "名字4",
              value1: "",
              value2: "",
              value3: "2017年-10月"
            },
            {
              all: "",
              name: "名字4",
              value1: "",
              value2: "",
              value3: "2017年-11月"
            },
            {
              all: "",
              name: "名字4",
              value1: "",
              value2: "",
              value3: "2017年-12月"
            }
          ];
          //进行赋值,为了后面编辑用,此方法位置不要动
          ctx.getSpanArr4Edit(_data);
          console.log(ctx.tableData3, "ctx.tableData3");
          ctx.getSpanArr(ctx.tableData3);
          ctx.getSpanArrOne(ctx.tableData3);
        },
        //改变分页事件已办理
        clickChangePage(currPage) {
          this.getGateStationList(currPage);
        },
        cellStyle({ row, column, rowIndex, columnIndex }) {
          return "padding:0px";
        },
        getRowClass({ row, column, rowIndex, columnIndex }) {
          return "height:0";
        },
        searchData: function() {
          let searchVal = this.formInline.searchVal;
        },
        setClass(gateState) {
          if (gateState == 0) {
            return "stateClass-a";
          }
          return "stateClass-b";
        },
        dialogQuickClose: function() {
          this.dialogQuick = false;
        },
        //前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性
        //index 0开始
        objectSpanMethod: function({ row, column, rowIndex, columnIndex }) {
          let length = this.tableData3.length - 1;
          // //合并第一列
          // if (columnIndex === 0) {
          //   console.log(columnIndex, "columnIndex");
          //   alert(columnIndex);
          //   if (rowIndex % length === 0) {
          //     return {
          //       rowspan: length + 1,
          //       colspan: 1
          //     };
          //   } else {
          //     return {
          //       rowspan: 0,
          //       colspan: 0
          //     };
          //   }
          // }
          //合并第一列
          if (columnIndex === 0) {
            alert(columnIndex);
            if (rowIndex % 2 === 0) {
              return {
                rowspan: 2,
                colspan: 1
              };
            } else {
              return {
                rowspan: 0,
                colspan: 0
              };
            }
          }
          //合并第二三列
        },
        //合并单元格,此方法需要后台进行名字进行排序
        cellMerge({ row, column, rowIndex, columnIndex }) {
          let length = this.tableData3.length;
          //第0列比较特殊,单独合并
          if (columnIndex === 0) {
            const _row = this.spanArrOne[rowIndex];
            const _col = _row > 0 ? 1 : 0;
            return {
              rowspan: _row,
              colspan: _col
            };
          }
          //1 2 5列进行合并
          if (columnIndex === 1 || columnIndex === 2 || columnIndex === 5) {
            const _row = this.spanArr[rowIndex];
            const _col = _row > 0 ? 1 : 0;
            return {
              rowspan: _row,
              colspan: _col
            };
          }
        },
        //1 2  5列合并的数据
        getSpanArr(data) {
          for (var i = 0; i < data.length; i++) {
            if (i === 0) {
              this.spanArr.push(1);
              this.pos = 0;
            } else {
              // 判断当前元素与上一个元素是否相同
              if (data[i].name === data[i - 1].name) {
                this.spanArr[this.pos] += 1; //需要合并的行数
                this.spanArr.push(0); //新增被合并的行
              } else {
                this.spanArr.push(1);
                this.pos = i; //新的需要合并的第几行数
              }
            }
          }
        },
        //0列合并的数据
        getSpanArrOne(data) {
          for (var i = 0; i < data.length; i++) {
            if (i === 0) {
              this.spanArrOne.push(1);
              this.posOne = 0;
            } else {
              this.spanArrOne[this.posOne] += 1; //需要合并的行数
              this.spanArrOne.push(0); //新增被合并的行
            }
          }
          console.log(this.spanArrOne, " this.spanArrOne");
        },
        //编辑用到的数据
        getSpanArr4Edit(data) {
          let ctx = this;
          var flagNum = 0;
          for (var i = 0; i < data.length; i++) {
            //首先不能编辑
            ctx.$set(data[i], "editing", false);
            if (i === 0) {
              ctx.spanArr4Edit.push(flagNum);
            } else {
              // 判断当前元素与上一个元素是否相同
              if (data[i].name === data[i - 1].name) {
                ctx.spanArr4Edit.push(flagNum); //还是同一个记录
              } else {
                ctx.spanArr4Edit.push(i);
                flagNum = i;
              }
            }
            //与编辑相对应
            ctx.$set(data[i], "flagNum", flagNum);
          }
          //最终赋值
          ctx.tableData3 = data;
          console.log(ctx.spanArr4Edit, "this.spanArr4Edit");
        },
        //快捷填写
        clickTodo: function(index, row) {
          this.dialogQuick = true;
          this.quickFlag = index;
          this.addform = {};
        },
        //快捷填写保存
        addSubmit: function() {
          let ctx = this;
          //赋值数据,取出哪一行需要进行赋值
          let idx = this.quickFlag;
          let datalength = ctx.tableData3.length;
          //每次快捷填写某一个分水口,所以此变量在此定义
          var initFlag = 0;
          for (let i = 0; i < datalength; i++) {
            if (idx === ctx.tableData3[i].flagNum) {
              if (initFlag == 0) {
                //value1 只赋值一次就行
                this.$set(ctx.tableData3[i], "value1", this.addform.w);
              }
              initFlag++;
              this.$set(ctx.tableData3[i], "value2", this.addform.q);
            }
          }
          this.dialogQuick = false;
          ctx.$message.success("操作成功");
          console.log(this.addform, "this.addform");
        },
        handleEdit(index, row) {
          let ctx = this;
          this.setEditFlag(index, 1);
          console.log(index);
          // this.prevValue = JSON.parse(JSON.stringify(row));//保存之前的数据
        },
        handleCancle(index, row) {
          row.editing = false;
          // let prevContent = this.prevValue.bookname;
          // this.$set(row,"bookname",prevContent);
        },
        savemodify(index, row) {
          this.setEditFlag(index, 0);
          console.log(row, "row");
          console.log(this.tableData3, "改变后的table数据");
          console.log(
            JSON.stringify(this.tableData3),
            "JSON.stringify(this.tableData3)"
          );
        },
        //提交数据到后台
        submitToServe() {
          let ctx = this;
          let dataResult = JSON.parse(JSON.stringify(this.tableData3));
          var result = 0;
          //调用后台保存方法
          // ctx.$api.addWaterApply(dataResult).then(res => {
          //   if (res.code == "0") {
          //       result =1;
          //   }
          // });
          console.log(dataResult, "提交到后台的数据");
          //return result;
          return 1;
        },
        //编辑输入框显示与隐藏0 隐藏 1显示
        setEditFlag: function(index, flag) {
          let ctx = this;
          let datalength = ctx.tableData3.length;
          let flagNum = ctx.spanArr4Edit[index];
          for (let i = 0; i < datalength; i++) {
            if (flag == 1) {
              if (flagNum === ctx.tableData3[i].flagNum) {
                //循环遍历改变可编辑的标记
                this.$set(ctx.tableData3[i], "editing", true);
              }
            } else {
              //循环遍历改变可编辑的标记
              this.$set(ctx.tableData3[i], "editing", false);
            }
          }
        }
      },
      filters: {
        iswarnFlt(val) {
          return val == 0 ? "否" : "是";
        }
      }
    };
    </script>
    <style lang="scss" scoped>
    .waterApplyTable {
      height: 100%;
    }
    </style>

    以上就是Element Table行的动态合并及数据编辑示例的详细内容,更多关于Element Table行动态合并编辑的资料请关注易盾网络其它相关文章!

    上一篇:npm i报错以及解决方案实战案例
    下一篇:没有了
    网友评论