element ui表格<el-table> 合并单元格

效果图如下

点击新增动物按钮,会新增一整行的数据 ,如果点击右侧操作按钮中的添加按钮,会添加一行小狗以右的数据,而小狗以前的数据和第一行数据合并一行。

<template>
  <div>
    <div style="magin-bottom: 20px; text-align: left">
      <el-row>
        <el-col :span="24">
          <el-button class="myBtn" @click="addDongWu()" type="primary"
            >新增动物</el-button
          >
        </el-col>
      </el-row>
    </div>
    <el-table :data="tableData" :span-method="spanMethod" style="width: 100%">
      <el-table-column prop="leftKey" label="动物">
        <template slot-scope="scope">
          <el-input v-model="scope.row.dongwu"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="leftKey" label="日期">
        <template slot-scope="scope">
          <!-- <div>{
   
   { scope.row.date }}</div> -->
          <el-input v-model="scope.row.date"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="leftKey" label="姓名">
        <template slot-scope="scope">
          <el-input v-model="scope.row.name"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="leftKey" label="年龄">
        <template slot-scope="scope">
          <el-input v-model="scope.row.age"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="xiaogou" label="小狗">
        <template slot-scope="scope">
          <el-input v-model="scope.row.xiaogou"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="xiaomao" label="小猫">
        <template slot-scope="scope">
          <el-input v-model="scope.row.xiaomao"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="xiaoya" label="小鸭">
        <template slot-scope="scope">
          <el-input v-model="scope.row.xiaoya"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="oprate" label="操作">
        <template slot-scope="scope">
          <button @click="addXiaoGou(scope.row)">添加</button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>

export default {
  components: {},
  data () {
    return {
      tableData: [],
      spanProps: ['leftKey'],  // 需要合并行的字段
    };
  },
  methods: {
    addDongWu () {  // 新增一行动物
      // 自定义一个字段叫leftKey,用来作为合并的标识
      const data = [{ dongwu: '', date: '', name: '', age: '', xiaogou: '', xiaomao: '', xiaoya: '', leftKey: `dongwu${this.tableData.length + 1}` }];  // 新增一条数据
      let newData = [...this.tableData, ...data];
      newData = newData.map((item, index) => { return { ...item, rowIndex: index } });   // 给每一行添加rowIndex字段
      this.tableData = [...newData];

    },
    addXiaoGou (row) {  // 新增一行小狗
      // leftKey:row.leftKey这句代码的意思是点击这个新增按钮时leftKey是取上一行的leftKey,leftKey的值相同就合并
      const data = { dongwu: '', date: '', name: '', age: '', xiaogou: '', xiaomao: '', xiaoya: '', leftKey: row.leftKey };  // 新增一条数据
      this.tableData.splice(row.rowIndex + 1, 0, data)  // 向数组指定位置插入一条数据
      this.tableData = this.tableData.map((item, index) => { return { ...item, rowIndex: index } });   // 给每一行添加rowIndex字段
      console.log('this.tableData', this.tableData);
    },
    // 合并行
    //参数:dataSource-表格数据,spanProps-需要进行合并计算的字段列表,rowIndex-当前行数,columnIndex-当前列数,column-当前列
    spanMethodFunc (dataSource = [], spanProps = [], rowIndex, columnIndex, column) {
      // if (columnIndex >= spanProps.length || !spanProps[columnIndex]) {
      if (!spanProps.includes(column.property)) {
        // 根据传入的字段列表,判断不需要合并的列
        return [1, 1];
      } else {
        //使用try-catch,如果方法错误返回错误信息
        try {
          // let _spanProps = spanProps.slice(columnIndex, columnIndex + 1); //截取需要用到判断的字段名
          // 过滤出需要合并的当前列字段
          let _spanProps = spanProps.filter(item => item == column.property);
          // 判断是否从本行开始合并
          let merge = _spanProps.some((item) => {
            // 如果当前行所需要判断合并的字段中有一个跟前一条数据不一样,本条数据即为合并的起点,第一条数据直接为合并起点
            return rowIndex == 0 || (item && dataSource[rowIndex][item] != dataSource[rowIndex - 1][item]);
          });
          // 如果本条数据是合并起点,获取需要合并的数据条数
          if (merge) {
            let _list = dataSource.slice(rowIndex); //截取从本条数据开始的列表
            // 获取合并行数
            let _lineNum = _list.findIndex((item, index) => {
              //同merge判断,找到合并的终点
              return (
                index &&
                _spanProps.some((item1) => {
                  return item1 && item[item1] != _list[0][item1];
                })
              );
            });
            // 合并行数为-1时,输出_list的长度,否则输出_lineNum
            return [_lineNum === -1 ? _list.length : _lineNum, 1];
          } else {
            // 否则,返回[0,0],即本条数据被合并
            return [0, 0];
          }
        } catch (err) {
          console.error("spanMethodFunc error:", err);
        }
      }
    },
    // 合并行
    spanMethod ({ row, column, rowIndex, columnIndex }) {
      return !this.spanProps ||
        this.spanProps.length === 0 ? false : this.spanMethodFunc(this.tableData, this.spanProps, rowIndex, columnIndex, column)
    },
  },
  mounted () {

  }
};
</script>

<style scoped>
</style>

猜你喜欢

转载自blog.csdn.net/weixin_49393290/article/details/121210823