element-ui 或者 ant-design-vue 的表格实现类似订单一行显示两行内容可以实现吗?

image.png
想用element-ui 或者 ant-design-vue 的表格改造实现类似这种订单表格效果的表格可以做吗?还是说只能用原生Html的方式去实现?

阅读 1k
avatarAI BotBETA

使用 Element UI 或 Ant Design Vue 的表格组件实现类似订单一行显示两行内容的效果是可行的,但可能需要一些额外的样式定制或结构上的调整。这两种 UI 框架都提供了丰富的自定义能力,包括自定义单元格的渲染。

Element UI 示例

在 Element UI 中,你可以使用 scoped slot 来自定义表格的每一列,包括合并行或列的显示。但直接一行显示两行内容可能需要借助 CSS 样式来调整行高或使用额外的容器来分组内容。

一个基本的思路是使用 row-class-namerow-style 来为特定行添加样式,或者通过自定义渲染函数来生成包含两行数据的单元格。

Ant Design Vue 示例

Ant Design Vue 同样支持自定义渲染表格列,可以使用 scopedSlots 或 Vue 的 render 函数来定义单元格内容。你可以通过 CSS 样式或者 Vue 的条件渲染来在一行内显示两行内容的效果。

实现思路

  1. 自定义渲染函数:使用 Vue 的 scoped slotrender 函数来自定义单元格的渲染逻辑。
  2. CSS 样式调整:利用 CSS 的 display: flexflex-direction: column 等属性来在单个单元格内实现多行布局。
  3. 分组渲染:如果数据逻辑上需要分为两行显示,可以在数据源上进行处理,将需要分行的数据组织为子数组或对象,然后在渲染时根据这些分组来渲染多行。

示例代码片段(概念性)

这里不给出完整的代码,因为实现会依赖于具体的数据结构和设计需求,但以下是一个概念性的伪代码示例:

<template>
  <a-table :columns="columns" :dataSource="data" rowKey="id">
    <template #customCell="{ text, record }">
      <div style="display: flex; flex-direction: column;">
        <div>{{ text.line1 }}</div>
        <div>{{ text.line2 }}</div>
      </div>
    </template>
  </a-table>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        // ... 其他列配置
        {
          title: '订单详情',
          customRender: ({ record }) => ({
            children: <div>{/* 自定义渲染逻辑,可能包含多行 */}</div>,
            attrs: {},
          }),
          // 或者使用 scoped slot
        },
      ],
      data: [
        // 假设每个订单项包含需要分行的数据
      ],
    };
  },
};
</script>

注意:上面的代码示例结合了 Ant Design Vue 的 customRender(实际上 Ant Design Vue 不直接支持此属性,这里仅作为概念说明)和 Vue 的插槽(slot)概念。在实际应用中,你可能需要根据框架的文档来调整实现方式。

总之,使用 Element UI 或 Ant Design Vue 的表格组件实现一行显示两行内容的效果是可行的,但需要一定的自定义和样式调整。

1 个回答

表格嵌套表格就可以了。
图片.png

<template>
  <el-table :data="tableData" border style="width: 100%">
    <el-table-column type="selection" width="55" />
    <el-table-column prop="data" label="数据" >
      <template #default="scope">
        <el-table :data="[scope.row]" border style="width: 100%">
          <el-table-column prop="date" label="Date" width="180" />
          <el-table-column prop="name" label="Name" width="180" />
          <el-table-column prop="address" label="Address" />
      </el-table>
      </template>
    </el-table-column>
  </el-table>
</template>

<script lang="ts" setup>
const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
]
</script>

Element Plus Playground


更新

就是做一下行列合并,把 tbody 中的后续几列全部合并到一列里面,然后给单元格设置 padding:0 就好了,我这边就直接粗暴的使用 !important 提升权重了,OP你自行调整。

图片.png

<template>
  <el-table :data="tableData" :span-method="objectSpanMethod" border style="width: 100%">
    <el-table-column type="selection" width="55" />
    <el-table-column prop="name" label="Name" class-name="my-column">
      <template #default="{row}">
        <el-table :data="[row]" style="width: 100%">
          <el-table-column prop="desc" :label="`Name: ${row.name}, Address:${row.address}`" />
          <el-table-column prop="name" label="" width="120" />
          <el-table-column prop="date" label="" width="120" />
      </el-table>
      </template>
    </el-table-column>
    <el-table-column prop="date" label="Price" width="120" />
    <el-table-column prop="date" label="Date" width="120" />
  </el-table>
</template>

<script lang="ts" setup>
const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    desc:"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    desc:"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    desc:"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    desc:"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
  },
]


const objectSpanMethod = ({ row, column }) => {
  let span = { rowspan: 1, colspan: 0}
  if (column.label === 'Name') {
    span.rowspan = 1
    span.colspan = 3
  } 
  if (column.type === 'selection') {
    span.rowspan = 1
    span.colspan = 1
  } 
  return span
}
</script>
<style>
.my-column {
  padding: 0 !important;
}
.my-column > .cell {
  padding: 0 !important;
}
</style>

Element Plus Playground

推荐问题
宣传栏