当前位置: 首页 > article >正文

组件库TDesign的表格<t-table>的使用,行列合并以及嵌入插槽实现图标展示,附踩坑

碎碎念:有点难用,不丝滑(以下介绍的难点不是真的难,只是有点点点难用)

背景:需要实现表格的行列合并以及图标的嵌入,想到使用组件库组件来方便开发

链接:TDesign Web Vue Next

难点1:数据的定义

看到官方的代码实现,定义结构感觉有点乱

官方示例图:

官方代码:

这部分主要就是定义table结构,

data:表格数据;columns:表头结构

rowkey要定义,不然错误信息

rowspan-and-colspan:定义表格行列合并的规则(合并的框会框会覆盖后面的)

<template>
  <div>
    <t-table
      :bordered="true"
      :data="data"
      :columns="columns"
      row-key="i"
      :rowspan-and-colspan="rowspanAndColspan"
      resizable
      table-layout="fixed"
      lazy-load
    />
  </div>
</template>

然后是js里的

statusNameListMap定义的是type有关样式值,存关键的对象

data用new Array生成

colums里定义表头的结构,colspan定义的是列合并

rowspanAndColspan = ({ col,row, ,colIndex , rowIndex })

其中  col 是表头信息, row是一行的信息 ,colIndex是单元格列 index, rowIndex是单元格行 index

<script setup lang="jsx">
import { ErrorCircleFilledIcon, CheckCircleFilledIcon, CloseCircleFilledIcon } from 'tdesign-icons-vue-next';

const statusNameListMap = {
  0: { label: '审批通过', theme: 'success', icon: <CheckCircleFilledIcon /> },
  1: { label: '审批失败', theme: 'danger', icon: <CloseCircleFilledIcon /> },
  2: { label: '审批过期', theme: 'warning', icon: <ErrorCircleFilledIcon /> },
};

const data = new Array(6).fill(null).map((_, i) => ({
  i,
  status: i % 3,
  applicant: ['贾明', '张三', '王芳'][i % 3],
  channel: ['电子签署', '纸质签署', '纸质签署'][i % 3],
  type: ['审批通过', '已过期', '审批失败', '审批中'][i % 4],
  detail: {
    email: [
      'w.cezkdudy@lhll.au',
      'r.nmgw@peurezgn.sl',
      'p.cumx@rampblpa.ru',
      'b.nmgw@peurezgn.sl',
      'd.cumx@rampblpa.ru',
    ][i % 5],
  },
  needed: ['Y', 'N'][i % 1],
  description: ['宣传物料制作费用', 'algolia 服务报销', '相关周边制作费', '激励奖品快递费'][i % 4],
  createTime: '2021-11-01',
}));

const columns = [
  { colKey: 'applicant', title: '申请人', width: '100' },
  {
    colKey: 'status',
    title: '申请状态',
    width: '150',
    cell: (h, { row }) => {
      return (
        <t-tag shape="round" theme={statusNameListMap[row.status].theme} variant="light-outline">
          {statusNameListMap[row.status].icon}
          {statusNameListMap[row.status].label}
        </t-tag>
      );
    },
  },
  {
    colKey: 'description',
    title: '审批事项',
    width: 150,
  },
  {
    colKey: 'detail.email',
    title: '邮箱地址',
  },
  {
    colKey: 'channel',
    // 多行表头合并请参考「多级表头示例」
    title: '其他信息',
    // 仅适用于单行表头合并列
    colspan: 2,
    // 设置列样式,注释的示例代码有效
    // attrs: ({ type, col, row, colIndex, rowIndex }) => ({
    //   style: {
    //     color: 'blue',
    //   },
    // }),
  },
  {
    colKey: 'createTime',
    title: '创建时间',
  },
];

const rowspanAndColspan = ({ col, rowIndex, colIndex }) => {
  if (colIndex === 0 && rowIndex % 2 === 0) {
    return {
      rowspan: 2,
    };
  }
  if (col.colKey === 'description' && rowIndex === 1) {
    return {
      colspan: 2,
      rowspan: 2,
    };
  }
  if (col.colKey === 'email' && rowIndex === 4) {
    return {
      colspan: 2,
      rowspan: 2,
    };
  }
};
</script>

打印了下data的结构:发现每个字段都有,是个数组对象,所以合并的时候数据是会占位,并被前面的覆盖掉

难点二:样式修改

官方的样式只提供了表格的样式修改

1. 行的类名rowClassName设置

2. 列的类名className设置

3. attr: { style: { } }设置该列的内联样式

4. cell:表格的渲染函数,可自定义插槽作为该列,比如增加图标

5. title:表头的渲染函数,可自定义插槽作为表头,比如增加图标

6. render:可以渲染表头,也可以渲染单元格,相当于cell或title

官方代码:我这里只放部分对应的

//  第一种  (王芳那一行)
<t-table row-key="id" :data="data" :columns="columns" :row-class-name="getRowClassName">
    <template #footerSummary>
        <div class="t-table__row-filter-inner"><InfoCircleIcon />近期申请耗时较长</div>
    </template>
</t-table>

const getRowClassName = ({ rowIndex }) => {
  if (rowIndex === 2) return 'custom-third-class-name';
  return '';
};

.t-demo__style .t-table .custom-third-class-name > td {
  background-color: var(--td-brand-color-light);
  font-weight: bold;
}


//  第二种(第四列)
{
    colKey: 'channel',
    title: '签署方式',
    width: 120,
    align: 'right',
    className: () => {
      return 'custom-cell-class-name';
    },
  },

.t-table td.custom-cell-class-name {
  color: orange;
  font-weight: bold;
}


//  第三种 (第三列)
  {
    colKey: 'time',
    title: '申请耗时(天)',
    width: 120,
    align: 'center',
    // 设置单元格类名
    className: ({ row }) => {
      if (row.time >= 9) {
        return 'custom-cell-class-name';
      }
      return '';
    },
    attrs: ({ row }) => {
      if (row.time >= 9) {
        return {
          style: {
            fontWeight: 600,
            backgroundColor: 'var(--td-warning-color-light)',
          },
        };
      }
    },
  },

<t-table :data="data" :columns="columns" row-key="property" lazy-load>
      <!-- 自定义表头,title值为插槽名称  -->
  <template #title-slot-name>
        <div style="display: flex; align-items: center">
            <UserCircleIcon style="margin-right: 8px" />申请人</div>
  </template>
</t-table>

//  cell   colums里的  对应审批状态的单元格
{
    title: '审批状态',
    colKey: 'status',
    // 使用 cell 方法自定义单元格:
    cell: (h, { row }) => {
      return (
        <t-tag shape="round" theme={statusNameListMap[row.status].theme} variant="light-outline">
          {statusNameListMap[row.status].icon}
          {statusNameListMap[row.status].label}
        </t-tag>
      );
    },
  },


//  title   对应有图标的表头
{
    colKey: 'applicant',
    title: 'title-slot-name',
    width: 120,
  },


//  render   对应申请时间
{
    colKey: 'createTime',
    // render 可以渲染表头,也可以渲染单元格。但 title 只能渲染表头,cell 只能渲染单元格
    render(h, context) {
      const { type, row, col } = context;
      return {
        title: '申请时间',
        cell: row && row[col.colKey],
      }[type];
    },
  },

然后以下是我的使用,我的实现结果,贴图:

表格结构定义:

colums: 表头 定义字段,宽度,行合并/列合并,表头对应该列的样式

table:定义表格数据,其中字段对应表头字段,然后可以设置行、列合并(非自带),传给下面函数处理

tableList:由于没设标识,所以给数据增加index作为标识,不然会报错
rowspanAndColspan:函数,设置单元格所占的行,列的格子数,会对满足条件的单元格使用

attrs设置了样式,cell,title绑定了插槽

// 表头 定义字段,宽度,行合并/列合并,表头对应该列的样式
const columns = [
  {
    colKey: 'compare',
    title: '测试1',
    width: '200px',
    colspan: 2,
    attrs: () => {
      return {
        style: {
          fontWeight: 600,
        },
      }
    },
  },
  {
    colKey: 'content',
    title: '测试2',
    width: '279px',
    align: 'center',
  },
  {
    colKey: '测试3',
    title: 'title-vip',
    width: '239px',
    align: 'center',
    cell: 'vip',
    attrs: () => {
      return {
        style: {
          backgroundColor: 'rgba(239, 158, 0, 0.1)',
          border: '1px solid #FFD583',
        },
      }
    },
  },
  {
    colKey: 'normal',
    title: '测试4',
    width: '239px',
    align: 'center',
    cell: 'normal',
  },
  {
    colKey: 'other',
    title: '测试5',
    width: '239px',
    align: 'center',
    cell: 'other',
  },
]

//  定义表格数据,其中字段对应表头字段,然后可以设置行、列合并,这里主要是传给下面函数处理
const table = [{
  compare: '项目',
  content: '项目',
  vip: true,
  normal: 'test',
  other: false,
  colspan: 2,

}, {
  compare: '项目',
  vip: true,
  normal: 'test',
  other: '其他',
  colspan: 2,
}, {
  compare: '项目',
  content: '项目',
  vip: true,
  normal: true,
  other: false,
  rowspan: 4,
}, {
  compare: '项目',
  content: '项目',
  vip: true,
  normal: true,
  other: false,
}, {
  compare: '项目',
  content: '项目',
  vip: true,
  normal: true,
  other: false,
}, {
  compare: '项目',
  content: '企业',
  vip: true,
  normal: true,
  other: false,
}, {
  compare: '项目测试',
  content: '',
  vip: true,
  normal: true,
  other: '其他',
  colspan: 2,
}, {
  compare: '下载',
  content: '',
  vip: true,
  normal: '其他',
  other: '其他',
  colspan: 2,
}, {
  compare: '项目查看	',
  content: '',
  vip: true,
  normal: '其他',
  other: '其他',
  colspan: 2,
}, {
  compare: '项目查看',
  content: '项目1',
  vip: true,
  normal: '其他',
  other: '其他',
  rowspan: 4,
}, {
  compare: '项目查看',
  content: '项目2',
  vip: true,
  normal: true,
  other: false,
}, {
  compare: '项目查看',
  content: '项目3',
  vip: true,
  normal: true,
  other: false,
}, {
  compare: '项目查看',
  content: '项目4',
  vip: '测试数据',
  normal: '其他',
  other: '其他',
}]

//  给数据增加index作为标识,不然会报错
const tableList = table.map((item, index) => ({
  ...item,
  index,
}))

// 这个是设置单元格所占的行,列的格子数
function rowspanAndColspan({ row, colIndex }) {
  if (colIndex === 0) {
    const colspan = row.colspan || 1
    const rowspan = row.rowspan || 1
    return {
      colspan,
      rowspan,
    }
  }
}

表格:

<div>
  <t-table
    :bordered="true"
    :data="tableList"
    :columns="columns"
    row-key="index"
    :rowspan-and-colspan="rowspanAndColspan"
    :resizable="false"
    lazy-load
  >
    <template #title-vip>
      <div class="cell-style font-600">
        <img src="../../assets/img/vip/icon-vip.png" 
             alt="" class="vipimg cell-img mr-1"> 测试3
      </div>
    </template>
    <template #vip="{ row }">
      <div v-if="row.vip === true" class="cell-style">
        <div class="true cell-img">
          <img src="../../assets/img/vip/icon-true.png" alt="">
        </div>
      </div>
      <div v-else>
        {{ row.vip }}
      </div>
    </template>
    <template #normal="{ row }">
      <div v-if="row.normal === true" class="cell-style">
        <div class="true cell-img">
          <img src="../../assets/img/vip/icon-true.png" alt="">
        </div>
      </div>
      <div v-else>
        {{ row.normal }}
      </div>
    </template>
    <template #other="{ row }">
      <div v-if="row.other === false" class="cell-style">
        <div class="false cell-img">
          <img src="../../assets/img/vip/icon-false.png" alt="">
        </div>
      </div>
      <div v-else>
        {{ row.other }}
      </div>
    </template>
  </t-table>
</div>

踩坑1:

设置headerAffixedTop的吸顶,会因为表头合并而出现滚动条的问题,升级版本也没办法

解决方法:不能完全解决,只能采取相似效果实现

将表头的colspan:2的合并给去掉,然后把后边的第一个格子设置className,定义样式,左边框去掉

踩坑2:

表头的样式定义:无直接设置表头的样式

1.  使用className设置实现,但是需要设置每一个

2.  使用样式穿透

:deep(.t-table__th-cell-inner) {
  font-weight: 600;
  color: black;
}


http://www.kler.cn/a/455476.html

相关文章:

  • 解决VMware的ubuntu22虚拟机没有网络
  • 41 stack类与queue类
  • 前端往后端传递参数的方式有哪些?
  • yolov5及其算法改进
  • C++--------继承
  • SQL 实战:日期与时间函数 – 统计数据的时间跨度与趋势
  • UGUI源码分析 --- UI的更新入口
  • “游戏信息化”:游戏后台系统的未来发展
  • Windows 11 系统下,通过 WSL(Windows Subsystem for Linux)里的 Ubuntu 24.04 安装 CUDNN 记录
  • 【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
  • 面试题整理13----deployment和statefulset区别
  • DeepSpeed的json配置讲解:ds_config_zero3.json
  • 【代码随想录|动态规划背包问题应用】
  • 使用VS Code开发ThinkPHP项目
  • windows nvm 切换node版本后,npm找不到
  • Transformer++架构:突破性的创新与优化
  • 注意⚠️:矩阵系统源码开发/SaaS矩阵系统开源/抖音矩阵开发优势和方向
  • AI绘图开源工具Stable Diffusion WebUI前端API调用
  • Springboot jar包加密加固并进行机器绑定
  • 知迪科技荣获合肥高新区“瞪羚企业” “潜在独角兽企业”双认证
  • JVM -垃圾回收机制
  • 山东大学软件学院2024秋季大数据安全期末
  • Docker Container 可观测性最佳实践
  • LeetCode-两数之和(001)
  • mysql索引的理解
  • LLM预训练recipe — 摘要版