A tabela de elementos mescla linhas e edita dados dinamicamente

Descreva primeiro os requisitos, veja a figura abaixo

1: Mesclar linhas dinamicamente, como mostrado na figura, a primeira coluna é mesclada, a segunda coluna e a terceira coluna e a quarta coluna são mescladas de acordo com o nome

2: Você pode editar dinamicamente a terceira e a quarta colunas e só pode editar a terceira e a quarta colunas pertencentes a esta linha mesclada. Por exemplo, depois que o primeiro botão de edição é clicado, apenas as três primeiras linhas podem ser editadas

3: Os dados da primeira coluna são baseados na adição da terceira coluna

4: Clique em Preenchimento rápido, você pode preencher rapidamente a terceira e a quarta colunas

Ideias

1: A segunda coluna, a terceira e a quarta coluna são mescladas de acordo com o nome, e o plano de fundo é classificado de acordo com o nome. A recepção sabe qual linha precisa ser mesclada resolvendo o nome em um loop. Eu encontrei um da Internet e mudou.

 A primeira coluna de casos especiais é simplesmente modificada de acordo com as idéias acima

código do 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: Você pode editar dinamicamente a terceira e a quarta colunas para resolver:

   Adicionar módulo de modelo, adicionar caixa de entrada de entrada e tag de expansão dentro, controle por atributo, eu controlo retirando dados de fundo, adicionando edição de atributo personalizado após travessia, a fim de editar apenas a terceira coluna e a primeira mesclada por nome Para quatro colunas, Adicionei o atributo flagNum e as linhas com o mesmo nome têm o mesmo flagNum. O que imprimi aqui é que as linhas 0-2 são 0, as linhas 3 a 5 são 3, as linhas 9 a 9 são 6 e assim por diante, pode encontrar a regra é A primeira linha no início, quando você clica no primeiro botão de edição, o índice passado é 0, então de acordo com o flagNum match 0-2 linhas podem ser editadas, o seguinte é a mesma lógica

código do 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: Os dados da primeira coluna são baseados na adição da terceira coluna

Você pode usar o ouvinte para monitorar profundamente os dados transmitidos de segundo plano

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 é relativamente simples, ou seja, uma caixa de entrada aparece, clique em OK para trazer o valor para esta página para preencher

Diretamente no 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");
    },

-----------------------------------Linha divisória------------- -----------------------------------

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

 

Acho que você gosta

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