Element-UI 中关于 Table 的几个功能点简介(行列的合并和样式、合计行配置等)

〇、前言

本文记录了关于 Element 框架中 Table 的几个功能点,后续将持续更新。

el-table 官网地址:https://element.eleme.cn/#/zh-CN/component/table#table-column-scoped-slot

一、合并行或列,使用属性 span-method

默认参数:Function({ row, column, rowIndex, columnIndex })

其中,row:就是行数据,可以通过属性直接取值,例如:row.columName。

column:是列对象,包含列的全部属性,例如:列属性名(property)、列名称(label)、id、列宽度(realWidth)等等。

行索引(rowIndex)和列索引(columnIndex)都是从 0 开始计数。

如下示例,属性引用和方法体:

<el-table
  。。。
  :span-method="tableSpanMethod"
>
  <el-table-column fixed="left" prop="xiangmumc" label="项目名称" width="150" />
</el-table>
tableSpanMethod({ row, column, rowIndex, columnIndex }) {
    if(row.xuhao == 1){ // 通过 row 可以取行内的任一值,来作为判断的依据
        if(columnIndex <= 10 || columnIndex == 17){
            return [2,1]; // 合并两行一列
        }else if (columnIndex === 11) {
            return [1,2]; // 合并一行两列
        }
        else
            return [0,0]; // 已经合并的列直接返回空
    }
    else if(row.xuhao == 2){
        if(columnIndex<=10||columnIndex== 17){
            return [0, 0]; // 已经合并的列直接返回空
        }else
            return [1, 1]; // 正常显示就返回一行一列
    }
},

二、单元格样式控制

单元格样式控制和行列合并方法参数类似,Function({row, column, rowIndex, columnIndex}),不同点就是,cellStyle 支持 Object 类型,直接讲样式写进 Table 属性中。

  • Object 方式

当表格中的样式统一,就可以直接将样式写在 Table 属性中。如下示例:

<el-table
  。。。
  :cell-style="{'textAlign':'center','fontWeight':'bold'}"
>
  <el-table-column fixed="left" prop="xiangmumc" label="项目名称" width="150" />
</el-table>
  • 通过回调方法方式

当样式有个性化需求,就需要在 cellStyle 方法中,通过行和列索引来单独配置。如下示例:

<el-table
  。。。
  :cell-style="cellStyleMethod"
>
  <el-table-column fixed="left" prop="xiangmumc" label="项目名称" width="150" />
</el-table>
cellStyleMethod({row, column, rowIndex, columnIndex}){
  if(row.xiangmumc == "项目名称-1" || row.xiangmumc == "项目名称-2")
    return {textAlign:'center',fontWeight:'bold'}; // 直接返回 css 样式
  if(columnIndex == 7){ // 第几列,从 0 开始
    return {textAlign:'center'};
  }
  else if(columnIndex >= 0 && columnIndex <= 3){
    return {textAlign:'left'};
  }
  else{
    return {textAlign:'right'}; // 直接返回 css 样式
  }
},

三、单元格中的空格、换行、回车、制表符的处理

这与 CSS 的 white-space 属性相关,它用于设置如何处理元素内的空白字符。

若要显示文本中的空白字符,可配置为:

:cell-style="{whiteSpace:'pre-wrap'}"
/* 或全局配置样式 */
.el-table .cell {
  white-space: pre;
}

white-space 属性都有哪些值?

normal 默认值。空白字符会被【删除】。文本内容过长会默认换行。
nowrap 空白字符会被【删除】。文本默认不进行换行,除非遇到<br>。
pre 空白字符【保留】。仅在遇到换行符或 <br> 元素时才会换行。
pre-wrap 空白字符【保留】。在遇到换行符或 <br> 元素时,或文本内容过长会默认换行。
pre-line 空白字符会被【删除】。在遇到换行符或 <br> 元素时,或文本内容过长会默认换行。
break-spaces 类似 pre-wrap,空白字符【保留】,任何保留的空白序列总是占用空间,包括行末的。每个保留的空白字符后(包括空白字符之间)都可以被截断。保留空间占用而不会挂起,从而影响整个文本的占用空间。

什么是挂起:当一行代码的末尾有多余的空格时,这些空格不会显示在屏幕上,但仍然占用了存储空间。

参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/white-space    

四、合计行

关于合计行的配置项有以下几个:

  • show-summary:显示合计行,值为 Boolean 类型,默认 true。
  • sum-text:配置合计行第一列显示文字,为空或缺省默认‘合计’。
  • summary-method:自定义合计计算方法。

基础数据导入:

selectData:[], // 手动选择行动态列表
tableData: [{ // 表默认数据
  id: '12987122',
  name: '123',
  amount1: '234文本',
  amount2: '3.2',
  amount3: 10
}, {
  id: '12987123',
  name: '王小虎',
  amount1: '165',
  amount2: '4.43',
  amount3: 12
}, {
  id: '12987124',
  name: '王小虎',
  amount1: '324',
  amount2: '1.9',
  amount3: 9
}, {
  id: '12987125',
  name: '王小虎',
  amount1: '621',
  amount2: '2.2',
  amount3: 17
}, {
  id: '12987126',
  name: '王小虎',
  amount1: '539',
  amount2: '4.1',
  amount3: 15
}]

4.1 通过合计方法自定义合计显示

通过属性 :summary-method="getSummaries" 配置合计方法,如下示例:

<el-table
  :data="tableData"
  border
  height="200"
  :summary-method="getSummaries"
  show-summary
  style="width: 100%; margin-top: 20px">
  <el-table-column
    prop="id"
    label="ID"
    width="180">
  </el-table-column>
  <el-table-column
    prop="name"
    label="姓名">
  </el-table-column>
  <el-table-column
    prop="amount1"
    label="数值 1(元)">
  </el-table-column>
  <el-table-column
    prop="amount2"
    label="数值 2(元)">
  </el-table-column>
  <el-table-column
    prop="amount3"
    label="数值 3(元)">
  </el-table-column>
</el-table>
getSummaries(param) {
  const { columns, data } = param;
  const sums = [];
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '总价:'; // 首列添加自定义合计文字
      return;
    }
    const values = data.map(item => Number(item[column.property]));
    if ((column.property=="amount1" || column.property=="amount2" // 只合计指定行,通过列属性判断
         || column.property=="amount3") && !values.every(value => isNaN(value))) {
      sums[index] = values.reduce((prev, curr) => {
        const value = Number(curr);
        if (!isNaN(value)) { // 若不能转成数字就不进行累加
          return prev + curr;
        } else {
          return prev;
        }
      }, 0);
      sums[index] += ' 元'; // 统一给数字加单位
    } else {
      sums[index] = '';
    }
  });
  return sums;
}

效果如下图:

4.2 动态按照勾选行进行合计

在上一节的基础上进行改进。

首先添加一列勾选框,type="selection",然后添加勾选变更事件 selection-change,如下示例:

<el-table 
  :show-summary="table_show_summary"
  :summary-method="getSummaries"
  @selection-change="handleSelectionChange"
>
  <el-table-column type="selection" width="50" align="center"></el-table-column>
  。。。
</el-table>
handleSelectionChange(selection) {
  this.selectData = selection.map(item => item)
},
getSummaries(param) {
  const { columns, data } = param;
  const sums = [];
  columns.forEach((column, index) => {
    if (index === 1) {
      sums[index] = '总价:';
      return;
    }
  // const values = data.map(item => Number(item[column.property]));
  let values = []
  if (this.selectData.length===0) { // this.selectData 为所选择的行列表
    values = [];
  }else{
    values = this.selectData.map(item => Number(item[column.property]));
  }
    if ((column.property=="amount1" || column.property=="amount2"
         || column.property=="amount3") && !values.every(value => isNaN(value))) {
      sums[index] = values.reduce((prev, curr) => {
        const value = Number(curr);
        if (!isNaN(value)) {
          return prev + curr;
        } else {
          return prev;
        }
      }, 0);
      sums[index] += ' 元';
    } else {
      sums[index] = '';
    }
  });
  return sums;
}

效果如下图:

4.3 默认方式,将全部可以转成数字的数据进行合计

只用 show-summary 和 sum-text 来进行默认的合计显示。

如下一个简单的示例:

<el-table
  :data="tableData"
  border
  show-summary
  sum-text="合计-自定义"
  style="width: 100%">
  <el-table-column
    prop="id"
    label="ID"
    width="180">
  </el-table-column>
  <el-table-column
    prop="name"
    label="姓名">
  </el-table-column>
  <el-table-column
    prop="amount1"
    sortable
    label="数值 1">
  </el-table-column>
  <el-table-column
    prop="amount2"
    sortable
    label="数值 2">
  </el-table-column>
  <el-table-column
    prop="amount3"
    sortable
    label="数值 3">
  </el-table-column>
</el-table>

效果如下图:

由结果可知,默认的合计方法,是将全部列的全部可转成字符串的值全部求和。

4.4 遇到的其他问题

  • 不可给 table 配置固定高度

会引起固定列样式错乱。

<el-table height="570px"></el-table>
  • 右侧固定列 div[.el-table__fixed-right],出现左边框没有竖线问题

可以强制增加宽度,如下:

.el-table__fixed-right { // 当默认为 300px 宽度时,边框线不显示了,所以强制改为 301px
  width: 301px!important;
}
  • 左边有固定列,增加合计行后,横向滚动条被固定列遮挡问题

可以给 table 上层 div 配置显示顺序。

固定列的样式 .el-table__fixed-body-wrapper 有个 z-index 为 3,因此 table 所在的div 类样式 .el-table__body-wrapper 配置 z-index 就得小于 3,可以配置成 1 或者 2。

.el-table__body-wrapper{
  z-index: 2
}
  • 表格滚动条默认位置指定

通过属性 show-summary 来动态显示合计行时,会出现主表和合计行对应错乱的问题,此时就需要将滚动条默认渲染到横向起点,以避免错乱的现象。

// <el-table ref="tempTable"></el-table>
this.$nextTick(() => {
    this.$refs.tempTable.doLayout(); // 重新渲染 table
    this.$refs.tempTable.bodyWrapper.scrollLeft =0; // 将横向滚动条默认在最左边
    // this.$refs.tempTable.bodyWrapper.scrollTop =0; // 将纵向滚动条默认在最上边
});

另外,也可以将合计行配置在第一行或者滚动条以上,本文不再详述。

可参考:https://blog.csdn.net/qq_44170108/article/details/128037491  

https://www.cnblogs.com/pzw23/p/13601045.html

五、在列名后加解释性文本

多行文本的效果如下:

<el-table-column align="right" prop="testCol" label="测试列" width="150" :show-overflow-tooltip=true>
    <template slot="header">
        测试
        <el-tooltip popper-class="tooltip" placement="top">
            <i class="el-icon-question"></i>
            <div slot="content" class="tooltip-content">
                <p>这是第一行。</p>
                <p style="text-indent: 2em;">这是第二行,有缩进。</p>
            </div>
        </el-tooltip>
    </template>
</el-table-column>

如果只有文本仅为单行,就可以省略 p 标签,直接在 div 中添加文本。

posted @ 2024-11-28 15:12  橙子家  阅读(558)  评论(0编辑  收藏  举报