La tabla de elementos fusiona filas de forma dinámica y edita datos de forma dinámica

Primero describa los requisitos, vea la figura a continuación

1: Fusionar filas dinámicamente, como se muestra en la figura, la primera columna se fusiona, la segunda columna y la tercera columna y la cuarta columna se fusionan según el nombre

2: Puede editar dinámicamente la tercera y cuarta columnas, y solo puede editar la tercera y cuarta columnas que pertenecen a esta fila combinada. Por ejemplo, después de hacer clic en el primer botón de edición, solo se pueden editar las tres primeras filas

3: Los datos de la primera columna se basan en la adición de la tercera columna

4: Haga clic en Relleno rápido, puede completar rápidamente la tercera y cuarta columnas

Ideas

1: La segunda columna, la tercera columna y la cuarta columna se fusionan según el nombre, y el fondo se ordena según el nombre. La recepción sabe qué línea debe fusionarse resolviendo el nombre en un bucle. Encontré uno de Internet y lo cambió.

 La primera columna de casos especiales simplemente se modifica de acuerdo con las ideas anteriores.

código de elemento: 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"
    > 

código 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: Puede editar dinámicamente la tercera y cuarta columnas para resolver:

   Agregue el módulo de plantilla, agregue el cuadro de entrada de entrada y la etiqueta de intervalo dentro, control por atributo, controlo sacando datos de fondo, agregando edición de atributos personalizados después del recorrido, para editar solo la tercera columna y la primera combinada por nombre Para cuatro columnas, Agregué el atributo flagNum, y las líneas con el mismo nombre tienen el mismo flagNum. Lo que imprimí aquí es que las líneas 0-2 son 0, las líneas 3 a 5 son 3, las líneas 9 a 9 son 6, y así sucesivamente, usted puede encontrar la regla es La primera línea al principio, cuando hace clic en el primer botón de edición, el índice pasado es 0, por lo que, de acuerdo con el flagNum, se pueden editar las líneas 0-2, la siguiente es la misma lógica

código de elemento;

 <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>

código 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: Los datos de la primera columna se basan en la adición de la tercera columna

Puede usar el oyente para monitorear profundamente los datos transmitidos desde el fondo

Código:

 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; Esta lógica es relativamente simple, es decir, aparece un cuadro de entrada, haga clic en Aceptar para traer el valor a esta página para completar

Directamente en el código:

  //快捷填写保存
    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");
    },

-----------------------------------Línea divisoria------------- -----------------------------------

Pega el código completo
 

<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>

 

Supongo que te gusta

Origin blog.csdn.net/CarryBest/article/details/90645082
Recomendado
Clasificación