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

前端 - 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 因

  • (一) CSS语法 1.1 单位 ​ px全称pixel像素,是相对于屏幕分辨率而言的,它是一个绝对单位,但同时具有一定的相对性。因为在同一个设备上每个像素代表的物理长度是固定不变的,这点表现的是绝对性。但是在不同的设备之间每个设备像素所代表的物理长度是可以变化的,这点表现的是相对性。 ​ em是一个相对长度单位,具体的大小需要相对于父元素计算,比如父元素的字体大小为80px,那么子元素1em就表

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

  • 第十二部分 独立成分分析(Independent Components Analysis ) 接下来我们要讲的主体是独立成分分析(Independent Components Analysis,缩写为 ICA)。这个方法和主成分分析(PCA)类似,也是要找到一组新的基向量(basis)来表征(represent)样本数据。然而,这两个方法的目的是非常不同的。 还是先用“鸡尾酒会问题(cocktai