当前位置: 首页 > 知识库问答 >
问题:

前端 - el-table合并部分成功部分不成功?

韩善
2024-07-21

要实现同图片所示内容,前4列内容都是固定的。
渲染代码如下
<template>
<div>
<el-table :data="waterData" border :span-method="handleSpanM">

                                <el-table-column align="center" width="65"><template slot-scope="scope">{{scope.row.name }}</template></el-table-column>
                                <el-table-column align="center" width="70" label="系数">
                                    <template slot-scope="scope"><el-input size="mini" class="" v-model="scope.row.factor"></el-input></template>
                                </el-table-column>
                                <el-table-column align="center" width="120" label="等级分数">
                                    <template slot-scope="scope"><el-input size="mini" v-model="scope.row.grade"></el-input></template>
                                </el-table-column>
                                <el-table-column align="center" width="180" label="符号选择">
                                    <template slot-scope="scope">
                                        <div class="symbol">
                                            <span style="display: none;">{{ scope.row.symbol }}</span>
                                            <span class="symbol_range"></span>
                                        </div>
                                    </template>
                                </el-table-column>
                                <el-table-column width="120" v-for="(column,index) in 6"  :key="`column-${index}`" ><template slot="header" slot-scope="scope"><div><el-input  size="small" v-model="waterForm[`water${index + 1}_label`]" ></el-input>  </div>  </template> <template slot-scope="scope"><div><el-input  size="small" v-model="waterForm[`water${index + 1}_factor`]" ></el-input></div> </template></el-table-column> </div></template>

<script>
export default {
data() {

return {
    tableData:[
        {name:'降水(mm)',factor:'0.7',grade:'',symbol: '1','':'','':'','':'','':'','':'','':''},
        {name:'降水(mm)',factor:'0.7',grade:'',symbol: '1','':'','':'','':'','':'','':'','':''},
        {name:'降水(mm)',factor:'0.7',grade:'',symbol: '1','':'','':'','':'','':'','':'','':''},
        {name:'降水(mm)',factor:'0.7',grade:'',symbol: '1','':'','':'','':'','':'','':'','':''},
        {name:'风速(m/s)',factor:'0.5',grade:'',symbol: '0','':'','':'','':'','':'','':'','':''},
        {name:'风速(m/s)',factor:'0.5',grade:'',symbol: '0','':'','':'','':'','':'','':'','':''},
        {name:'风速(m/s)',factor:'0.5',grade:'',symbol: '0','':'','':'','':'','':'','':'','':''},
        {name:'风速(m/s)',factor:'0.5',grade:'',symbol: '0','':'','':'','':'','':'','':'','':''},
    ],
    colFields:['name','factor','grade','symbol','','','','','',''],
    spanArr:[],waterForm:{}, };

},
methods: {

getSpanArr() {
  for (let i = 0; i < this.tableData.length; i++) {
    let row = i;
    // let col = i % this.colCount;
    if (row === 0) {
      // i 表示行 j表示列
      for (let j = 0; j < this.colFields.length; j++) {
        this.spanArr[i * this.colFields.length + j] = {
          rowspan: 1,
          colspan: 1,
        };
      }
    } else {
      for (let j = 0; j < this.colFields.length; j++) {
        if (
          this.colFields[j] == "name" ||
          this.colFields[j] == "factor" ||
          this.colFields[j] == "symbol"
        ) { // 指定合并哪些列
        /*this.tableData[row]["School"] !==
              this.tableData[row - 1]["School"]*/
          if (
            this.tableData[row][this.colFields[j]] !==
              this.tableData[row - 1][this.colFields[j]]
          ) { // 哪些不合并:School不一样的,不合并
            this.spanArr[row * this.colFields.length + j] = {
              rowspan: 1,
              colspan: 1,
            };
          } else if (
            this.tableData[row][this.colFields[j]] ===
            this.tableData[row - 1][this.colFields[j]]
          ) {
            let beforeItem =
              this.spanArr[(row - 1) * this.colFields.length + j];
            this.spanArr[row * this.colFields.length + j] = {
              rowspan: 1 + beforeItem.rowspan,// 合并几列
              colspan: 1,// 合并几行
            };
            beforeItem.rowspan = 0;
            beforeItem.colspan = 0;
          } else {
            // rowspan 和 colspan 都为1表格此单元格不合并
            this.spanArr[row * this.colFields.length + j] = {
              rowspan: 1,
              colspan: 1,
            };
          }
        }
      }
    }
  }
  // 对数据进行倒序
  let stack = [];
  for (let i = 0; i < this.colFields.length; i++) {
    for (let j = 0; j < this.tableData.length; j++) {
      // console.log("i=" + i + " j=" + j);
      // i 表示列 j表示行
      if (j === 0) {
        if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
          stack.push(this.spanArr[j * this.colFields.length + i]);
        }
      } else {
        if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
          stack.push(this.spanArr[j * this.colFields.length + i]);
        } else {
          stack.push(this.spanArr[j * this.colFields.length + i]);
          while (stack.length > 0) {
            let pop = stack.pop();
            let len = stack.length;
            this.spanArr[(j - len) * this.colFields.length + i] = pop;
          }
        }
      }
    }
  }
  // console.log(this.spanArr);
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    return this.spanArr[rowIndex * this.colFields.length + columnIndex];
},}

},
mounted() {

this.getSpanArr();

},
渲染后结果image.png 怎么实现效果呢前4列除了第一列和第4列不可编辑其他都是可编辑的(输入框样式的,后面的表头也设置成可编辑的了)

系统能实现效果内容,现在发现第4列怎么都不合并。

共有1个答案

白云
2024-07-21

为了解答您的问题并实现期望的表格合并效果,我们需要对您的 span-method 函数进行调整。另外,您提到第4列(即“符号选择”列)不应该合并,而其他列(除了第一列)在相同的数据值下应该合并。

以下是调整后的 getSpanArr 方法以及如何使用它来定义 span-method。请注意,我已经去掉了之前方法中的一些复杂逻辑,因为这不是必需的,而且可能导致合并行为出错。

methods: {
  getSpanArr() {
    const colFields = this.colFields;
    for (let rowIndex = 0; rowIndex < this.tableData.length; rowIndex++) {
      for (let colIndex = 0; colIndex < colFields.length; colIndex++) {
        if (rowIndex === 0) {
          this.spanArr[rowIndex * colFields.length + colIndex] = {
            rowspan: 1,
            colspan: 1,
          };
        } else {
          // 判断是否合并,只针对非第一列和第四列
          if (colIndex !== 0 && colIndex !== 3) {
            // 检查当前列的数据是否与前一行相同
            if (
              this.tableData[rowIndex][colFields[colIndex]] ===
              this.tableData[rowIndex - 1][colFields[colIndex]]
            ) {
              // 合并,获取前一行的合并配置,并更新
              let previousItemSpan = this.spanArr[(rowIndex - 1) * colFields.length + colIndex];
              if (previousItemSpan.rowspan > 1) {
                // 如果前一行已经合并了,则不需要再增加rowspan
                this.spanArr[rowIndex * colFields.length + colIndex] = {
                  rowspan: 0, // 设置为0表示此单元格将被上一行合并
                  colspan: 1,
                };
              } else {
                // 否则,更新rowspan
                previousItemSpan.rowspan++;
                this.spanArr[rowIndex * colFields.length + colIndex] = {
                  rowspan: 0,
                  colspan: 1,
                };
              }
            } else {
              // 不合并,设置默认配置
              this.spanArr[rowIndex * colFields.length + colIndex] = {
                rowspan: 1,
                colspan: 1,
              };
            }
          } else {
            // 第一列和第四列不合并,设置默认配置
            this.spanArr[rowIndex * colFields.length + colIndex] = {
              rowspan: 1,
              colspan: 1,
            };
          }
        }
      }
    }
  },
  objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    if (this.spanArr.length) {
      return this.spanArr[rowIndex * this.colFields.length + columnIndex];
    }
  },
  // ... 其他方法
},
mounted() {
  this.getSpanArr();
},

此外,请确保在模板中正确地调用了 span-method

<el-table :data="tableData" border :span-method="objectSpanMethod">
  <!-- ... 其他列配置 ... -->
</el-table>

请注意,我已经将 span-method 绑定到 objectSpanMethod 方法上,并且使用 tableData 而不是 waterData(根据您的代码示例,我假设这是您想要的数据数组)。同时,我已经去掉了 colCount 的引用,因为它在您的代码中并未定义,并且我们直接使用 colFields.length 来确定列数。

最后,关于您提到的第4列(即“符号选择”列)的输入框样式,由于您已经使用了一个 <el-input> 组件,它默认就是可编辑的。如果您想要进一步自定义样式或行为,您可以在该组件上添加更多属性或样式类。

对于后面的表头,您已经使用 v-model 绑定到了 waterForm 对象上,这意味着这些表头也是可编辑的。如果您想要进一步自定义这些表头的行为或样式,您可以在模板中添加更多的逻辑或样式类。

 类似资料:
  • 本文向大家介绍table由哪几部分组成?相关面试题,主要包含被问及table由哪几部分组成?时的应答技巧和注意事项,需要的朋友参考一下 自己的答案: 看文档后发现漏掉的:

  • 正如我们前面解释的,非阻塞 I/O 不会强迫我们等待操作的完成。在这种能力的基础上,真正的异步 I/O 起到了更进一步的作用:一个异步方法完成时立即返回并直接或稍后通知用户。 正如我们将看到的,在一个网络环境的异步模型可以更有效地利用资源,可以快速连续执行多个调用。 Channel Channel 是 NIO 基本的结构。它代表了一个用于连接到实体如硬件设备、文件、网络套接字或程序组件,能够执行一

  • 第十一部分 主成分分析(Principal components analysis) 前面我们讲了因子分析(factor analysis),其中在某个 $k$ 维度子空间对 $x \in R^n$ 进行近似建模,$k$ 远小于 $n$,即 $k \ll n$。具体来说,我们设想每个点 $x^{(i)}$ 用如下方法创建:首先在 $k$ 维度仿射空间(affine space) ${\Lambda

  • 问题内容: 我想要一个表将显示一半的行,然后环绕并水平包装并显示另一半行,而不是一个长的垂直表。 我正在使用角度数据,希望能够将一个数据数组绑定到一张表,但是要像描述的那样将其水平跨两个部分。两个表是一个选项,但是这意味着我必须添加更多逻辑,如果可能的话,我希望避免使用。即,对于排序ID,必须先将数据集重新连接在一起并对其进行排序,然后再进行拆分。 任何指针表示赞赏。 问题答案: 您可以尝试使用C

  • 本文向大家介绍Android实现合并生成分享图片功能,包括了Android实现合并生成分享图片功能的使用技巧和注意事项,需要的朋友参考一下 有时候分享功能都是很需要分享一个当前屏幕的界面的截图因,以前做校内APP的时候用到过,拿出来分享分享, 用以前写过的自定义课表软件。 Android 自定义View课程表表格 看到的是图片只显示到11节处,下面的没有显示到 所以用到的 ScrollView 因

  • 这是为了俄罗斯方块。玻璃(蓝色)位于左侧,控制(红色面板)位于右侧。换句话说,现在我只想有一个框架分成两部分:左边(较宽)部分是蓝色,右边部分是红色。没别的了。但我似乎没能做到这一点。 所以,我的逻辑是:让框架有FlowLayout。然后,我添加了两个面板,这意味着它们将被放在一个行中。