Skip to content

示例

基础使用

只需配置data以及column后,data是数据源,column配置数组,用 label 属性来定义表格的列名。 可以使用 width 属性来定义列宽。其他属性对应El-TableTable-column中的属性

<template>
  <el-table-next :column="column" :data="tableData" />
</template>
<script setup lang="ts">
import type { ElTableColumnProps } from "el-table-next";
/* 引入ElTableColumnProps定义column可获得类型提示 */
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1516 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>
<template>
  <el-table-next :column="column" :data="tableData" />
</template>
<script setup lang="ts">
import type { ElTableColumnProps } from "el-table-next";
/* 引入ElTableColumnProps定义column可获得类型提示 */
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1516 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>
展开代码
Copy

Render 方式使用

render方式即是提供一个 render 渲染函数,给 render 函数传入 scope 参数(包含这一行数据、配置信息等信息),根据自己需求来渲染,如果 render 返回值是 html 类型,scriptlang属性应该是tsx或者jsx

如果使用render函数, 该列指定了prop属性的话,render的第一个参数是该列对应数据项,第二个参数才是scope配置项

<template>
  <div>
    <el-table-next :column="column" :data="tableData" />
  </div>
</template>

<script setup lang="tsx">
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "名字",
    prop: "name",
    render: (data, scope) => {
      const { row, column } = scope;
      const propKey = column.property;
      return (
        <div>
          render 结果 -- {row[propKey]}== {data}
        </div>
      );
    },
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>

<style lang="scss" scoped></style>
<template>
  <div>
    <el-table-next :column="column" :data="tableData" />
  </div>
</template>

<script setup lang="tsx">
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "名字",
    prop: "name",
    render: (data, scope) => {
      const { row, column } = scope;
      const propKey = column.property;
      return (
        <div>
          render 结果 -- {row[propKey]}== {data}
        </div>
      );
    },
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>

<style lang="scss" scoped></style>
展开代码
Copy

Slot 方式使用

slot方式即是在el-table-next中提供插槽,然后在column配置中指定运用插槽的名字,可以同时运用多个不同插槽

<template>
  <el-table-next :column="column" :data="tableData">
    <template #name="{ row }">
      <div>
        <ButtonNumber />
        <span>
          <code>name</code>
          插槽--{{ row.name }}
        </span>
      </div>
    </template>
    <template #default>
      <div>
        <span>
          默认插槽名字为
          <strong>default</strong>
        </span>
      </div>
    </template>
  </el-table-next>
</template>
<script setup lang="ts">
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "具名插槽",
    slotName: "name",
  },
  {
    label: "默认插槽",
    slotName: "default",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1516 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>
<template>
  <el-table-next :column="column" :data="tableData">
    <template #name="{ row }">
      <div>
        <ButtonNumber />
        <span>
          <code>name</code>
          插槽--{{ row.name }}
        </span>
      </div>
    </template>
    <template #default>
      <div>
        <span>
          默认插槽名字为
          <strong>default</strong>
        </span>
      </div>
    </template>
  </el-table-next>
</template>
<script setup lang="ts">
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "具名插槽",
    slotName: "name",
  },
  {
    label: "默认插槽",
    slotName: "default",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1516 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];
</script>
展开代码
Copy

带斑马纹表格

使用带斑马纹的表格,可以更容易区分出不同行的数据。

stripe 属性可以创建带斑马纹的表格。 如果 true, 表格将会带有斑马纹。

<template>
  <el-table-next stripe :column="column" :data="tableData" />
</template>
<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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>
<template>
  <el-table-next stripe :column="column" :data="tableData" />
</template>
<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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>
展开代码
Copy

带边框表格

默认情况下,Table 组件是不具有竖直方向的边框的, 如果需要,可以使用 border 属性,把该属性设置为 true 即可启用。

<template>
  <el-table-next border :column="column" :data="tableData" />
</template>
<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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>
<template>
  <el-table-next border :column="column" :data="tableData" />
</template>
<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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>
展开代码
Copy

带状态表格

可将表格内容 highlight 显示,方便区分「成功、信息、警告、危险」等内容。

可以通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class, 表明该行处于某种状态。

<template>
  <el-table-next :column="column" :data="data" :row-class-name="tableRowClassName"></el-table-next>
</template>

<script lang="ts" setup>
const data = [
  {
    date: "2016-05-02",
    name: "王小虎1",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎2",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎3",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎4",
    address: "上海市普陀区金沙江路 1518 弄",
  },
]
const column = [
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "name",
    label: "姓名",
  },
  {
    prop: "address",
    label: "地址",
  },
]
function tableRowClassName({ row, rowIndex }) {
  if (rowIndex === 1) {
    return "warning-row";
  } else if (rowIndex === 3) {
    return "success-row";
  }
  return "";
}
</script>

<style>
.el-table .warning-row {
  background: oldlace !important;
}

.el-table .success-row {
  background: #f0f9eb !important;
}
</style>
<template>
  <el-table-next :column="column" :data="data" :row-class-name="tableRowClassName"></el-table-next>
</template>

<script lang="ts" setup>
const data = [
  {
    date: "2016-05-02",
    name: "王小虎1",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎2",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎3",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-02",
    name: "王小虎4",
    address: "上海市普陀区金沙江路 1518 弄",
  },
]
const column = [
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "name",
    label: "姓名",
  },
  {
    prop: "address",
    label: "地址",
  },
]
function tableRowClassName({ row, rowIndex }) {
  if (rowIndex === 1) {
    return "warning-row";
  } else if (rowIndex === 3) {
    return "success-row";
  }
  return "";
}
</script>

<style>
.el-table .warning-row {
  background: oldlace !important;
}

.el-table .success-row {
  background: #f0f9eb !important;
}
</style>
展开代码
Copy

固定表头

纵向内容过多时,可选择固定表头。

只要在 el-table-next 元素中定义了 height 属性,即可实现固定表头的表格,而不需要额外的代码。

<template>
  <el-table-next border :column="column" :data="tableData" :height="250" />
</template>

<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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',
  },
  {
    date: '2016-05-08',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-06',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-07',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
]
</script>
<template>
  <el-table-next border :column="column" :data="tableData" :height="250" />
</template>

<script lang="ts" setup>
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
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',
  },
  {
    date: '2016-05-08',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-06',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-07',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
]
</script>
展开代码
Copy

固定列

横向内容过多时,可选择固定列。

固定列需要使用 fixed 属性,它接受 Boolean 值 如果为 true, 列将被左侧固定. 它还接受传入字符串,left 或 right,表示左边固定还是右边固定。

<template>
  <el-table-next border :column="column" :data="tableData" />
</template>

<script setup lang="tsx">
const handleClick = () => {
  console.log("click");
};
const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
  {
    label: "Operations",
    width: 200,
    fixed: "right",
    render() {
      return (
        <>
          <el-button type="text" size="small" onClick={handleClick}>
            Detail
          </el-button>
          <el-button type="text" size="small">
            Edit
          </el-button>
        </>
      );
    },
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
];
</script>
<template>
  <el-table-next border :column="column" :data="tableData" />
</template>

<script setup lang="tsx">
const handleClick = () => {
  console.log("click");
};
const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
  {
    label: "Operations",
    width: 200,
    fixed: "right",
    render() {
      return (
        <>
          <el-button type="text" size="small" onClick={handleClick}>
            Detail
          </el-button>
          <el-button type="text" size="small">
            Edit
          </el-button>
        </>
      );
    },
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
];
</script>
展开代码
Copy

固定列和表头

横纵内容过多时,可选择固定列和表头。

固定列和表头可以同时使用,只需要将上述两个属性分别设置好即可。

<template>
  <el-table-next border :column="column" :data="tableData" height="250" />
</template>

<script setup lang="ts">
const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
<template>
  <el-table-next border :column="column" :data="tableData" height="250" />
</template>

<script setup lang="ts">
const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
展开代码
Copy

流体高度

当数据量动态变化时,可以为 Table 设置一个最大高度。

通过设置 max-height 属性为 Table 指定最大高度。 此时若表格所需的高度大于最大高度,则会显示一个滚动条

<template>
  <el-table-next border :column="column" :data="tableData" max-height="250">
    <template #default="scope">
      <el-button type="text" size="small" @click.prevent="deleteRow(scope.$index)"
        >Remove</el-button
      >
    </template>
  </el-table-next>
  <el-button class="mt-4" style="width: 100%" @click="onAddItem">Add Item</el-button>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const now = new Date();

const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
  {
    label: "Operations",
    fixed: "right",
    width: 120,
    slotName: "default",
  },
];

const tableData = ref([
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
]);

const deleteRow = (index: number) => {
  tableData.value.splice(index, 1);
};

const onAddItem = () => {
  now.setDate(now.getDate() + 1);
  tableData.value.push({
    date: formatDate(now, "yyyy-MM-dd")!,
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  });
};

function formatDate(date: string | Date, fmt: string) {
  if (typeof date == "string") {
    return date;
  }

  if (!fmt) fmt = "yyyy-MM-dd hh:mm:ss";

  if (!date || date == null) return null;
  const o = {
    "M+": date.getMonth() + 1, // 月份
    "d+": date.getDate(), // 日
    "h+": date.getHours(), // 小时
    "m+": date.getMinutes(), // 分
    "s+": date.getSeconds(), // 秒
    "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  };
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length));
  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
      );
  }
  return fmt;
}
</script>
<template>
  <el-table-next border :column="column" :data="tableData" max-height="250">
    <template #default="scope">
      <el-button type="text" size="small" @click.prevent="deleteRow(scope.$index)"
        >Remove</el-button
      >
    </template>
  </el-table-next>
  <el-button class="mt-4" style="width: 100%" @click="onAddItem">Add Item</el-button>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const now = new Date();

const column = [
  {
    prop: "date",
    fixed: true,
    width: 150,
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "state",
    label: "State",
    width: 120,
  },
  {
    prop: "city",
    label: "City",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    width: 360,
  },
  {
    prop: "zip",
    label: "Zip",
    width: 180,
  },
  {
    label: "Operations",
    fixed: "right",
    width: 120,
    slotName: "default",
  },
];

const tableData = ref([
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
]);

const deleteRow = (index: number) => {
  tableData.value.splice(index, 1);
};

const onAddItem = () => {
  now.setDate(now.getDate() + 1);
  tableData.value.push({
    date: formatDate(now, "yyyy-MM-dd")!,
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  });
};

function formatDate(date: string | Date, fmt: string) {
  if (typeof date == "string") {
    return date;
  }

  if (!fmt) fmt = "yyyy-MM-dd hh:mm:ss";

  if (!date || date == null) return null;
  const o = {
    "M+": date.getMonth() + 1, // 月份
    "d+": date.getDate(), // 日
    "h+": date.getHours(), // 小时
    "m+": date.getMinutes(), // 分
    "s+": date.getSeconds(), // 秒
    "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  };
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length));
  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
      );
  }
  return fmt;
}
</script>
展开代码
Copy

多级表头

数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。

只需要在 column的某一项配置 children 数组属性,然后再配置column就可以实现多级表头。

<template>
  <el-table-next border :column="column" :data="tableData" />
</template>

<script lang="ts" setup>
import type { ElTableColumnProps } from "el-table-next";
const column: ElTableColumnProps[] = [
  {
    prop: "date",
    width: 120,
    label: "Date",
  },
  {
    label: "Delivery Info",
    children: [
      {
        prop: "name",
        label: "Name",
      },
      {
        label: "Address Info",
        children: [
          {
            prop: "state",
            label: "State",
          },
          {
            prop: "city",
            label: "City",
            width: 120,
          },
          {
            prop: "address",
            label: "Address",
          },
          {
            prop: "zip",
            width: 120,
            label: "Zip",
          },
        ],
      },
    ],
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
<template>
  <el-table-next border :column="column" :data="tableData" />
</template>

<script lang="ts" setup>
import type { ElTableColumnProps } from "el-table-next";
const column: ElTableColumnProps[] = [
  {
    prop: "date",
    width: 120,
    label: "Date",
  },
  {
    label: "Delivery Info",
    children: [
      {
        prop: "name",
        label: "Name",
      },
      {
        label: "Address Info",
        children: [
          {
            prop: "state",
            label: "State",
          },
          {
            prop: "city",
            label: "City",
            width: 120,
          },
          {
            prop: "address",
            label: "Address",
          },
          {
            prop: "zip",
            width: 120,
            label: "Zip",
          },
        ],
      },
    ],
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
展开代码
Copy

单选

选择单行数据时使用色块表示。

Table 组件提供了单选的支持, 只需要配置 highlight-current-row 属性即可实现单选。 之后由 current-change 事件来管理选中时触发的事件,它会传入 currentRowoldCurrentRow。 如果需要显示索引,可以增加一列 el-table-column,设置 type 属性为 index 即可显示从 1 开始的索引号。

<template>
  <el-table-next
    ref="singleTableRef"
    :data="tableData"
    :column="column"
    highlight-current-row
    style="width: 100%"
    @current-change="handleCurrentChange"
  ></el-table-next>
  <div style="margin-top: 20px">
    <el-button @click="setCurrent(tableData[1])">Select second row</el-button>
    <el-button @click="setCurrent()">Clear selection</el-button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { ElTable } from "element-plus";
const column = [
  {
    type: "index",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    width: 120,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
  },
];

interface User {
  date: string;
  name: string;
  address: string;
}

const currentRow = ref();
const singleTableRef = ref<InstanceType<typeof ElTable>>();

const setCurrent = (row?: User) => {
  singleTableRef.value!.setCurrentRow(row);
};
const handleCurrentChange = (val: User | undefined) => {
  currentRow.value = val;
};
const tableData: User[] = [
  {
    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>
<template>
  <el-table-next
    ref="singleTableRef"
    :data="tableData"
    :column="column"
    highlight-current-row
    style="width: 100%"
    @current-change="handleCurrentChange"
  ></el-table-next>
  <div style="margin-top: 20px">
    <el-button @click="setCurrent(tableData[1])">Select second row</el-button>
    <el-button @click="setCurrent()">Clear selection</el-button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { ElTable } from "element-plus";
const column = [
  {
    type: "index",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    width: 120,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
  },
];

interface User {
  date: string;
  name: string;
  address: string;
}

const currentRow = ref();
const singleTableRef = ref<InstanceType<typeof ElTable>>();

const setCurrent = (row?: User) => {
  singleTableRef.value!.setCurrentRow(row);
};
const handleCurrentChange = (val: User | undefined) => {
  currentRow.value = val;
};
const tableData: User[] = [
  {
    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>
展开代码
Copy

多选

你也可以选择多行。

实现多选非常简单: 手动添加一个 el-table-column,设 type 属性为 selection 即可; 除了多个选项,此示例还使用 show-overflow-tooltip:默认, 如果内容过长,它会分成多行。 若需要单行显示可以使用 show-overflow-tooltip 属性,它接受一个 Boolean,true 时多余的内容会在 hover 时以 tooltip 的形式显示出来。

<template>
  <el-table-next
    ref="multipleTableRef"
    :data="tableData"
    style="width: 100%"
    :column="column"
    @selection-change="handleSelectionChange"
  >
    <template #default="scope">Date:{{ scope.row.date }}</template>
  </el-table-next>
  <div style="margin-top: 20px">
    <el-button @click="toggleSelection([tableData[1], tableData[2]])"
      >Toggle selection status of second and third rows</el-button
    >
    <el-button @click="toggleSelection()">Clear selection</el-button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { ElTable } from "element-plus";

interface User {
  date: string;
  name: string;
  address: string;
}

const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<User[]>([]);
const toggleSelection = (rows?: User[]) => {
  console.log("🚀 ~ file: MultiSelectTable.vue ~ line 32 ~ toggleSelection ~ rows", rows);
  if (rows) {
    rows.forEach((row) => {
      // TODO: improvement typing when refactor table
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      multipleTableRef.value!.toggleRowSelection(row, undefined);
    });
  } else {
    multipleTableRef.value!.clearSelection();
  }
};
const handleSelectionChange = (val: User[]) => {
  multipleSelection.value = val;
};
const column = [
  {
    type: "selection",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    width: 120,
    slotName: "default",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    "show-overflow-tooltip": true,
  },
];
const tableData: User[] = [
  {
    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",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
];
</script>
<template>
  <el-table-next
    ref="multipleTableRef"
    :data="tableData"
    style="width: 100%"
    :column="column"
    @selection-change="handleSelectionChange"
  >
    <template #default="scope">Date:{{ scope.row.date }}</template>
  </el-table-next>
  <div style="margin-top: 20px">
    <el-button @click="toggleSelection([tableData[1], tableData[2]])"
      >Toggle selection status of second and third rows</el-button
    >
    <el-button @click="toggleSelection()">Clear selection</el-button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { ElTable } from "element-plus";

interface User {
  date: string;
  name: string;
  address: string;
}

const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<User[]>([]);
const toggleSelection = (rows?: User[]) => {
  console.log("🚀 ~ file: MultiSelectTable.vue ~ line 32 ~ toggleSelection ~ rows", rows);
  if (rows) {
    rows.forEach((row) => {
      // TODO: improvement typing when refactor table
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      multipleTableRef.value!.toggleRowSelection(row, undefined);
    });
  } else {
    multipleTableRef.value!.clearSelection();
  }
};
const handleSelectionChange = (val: User[]) => {
  multipleSelection.value = val;
};
const column = [
  {
    type: "selection",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    width: 120,
    slotName: "default",
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    "show-overflow-tooltip": true,
  },
];
const tableData: User[] = [
  {
    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",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
];
</script>
展开代码
Copy

排序

对表格进行排序,可快速查找或对比数据。

在列中设置 sortable 属性即可实现以该列为基准的排序, 接受一个 Boolean,默认为 false。 可以通过 Tabledefault-sort 属性设置默认的排序列和排序顺序。 可以使用 sort-method 或者 sort-by 使用自定义的排序规则。 如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件, 在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。 在本例中,我们还使用了 formatter 属性,它用于格式化指定列的值, 接受一个 Function,会传入两个参数:rowcolumn, 可以根据自己的需求进行处理。

<template>
  <el-table-next
    :data="tableData"
    :column="column"
    :default-sort="{ prop: 'date', order: 'descending' }"
    style="width: 100%"
  ></el-table-next>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface User {
  date: string;
  name: string;
  address: string;
}
const formatter = (row: User, column: TableColumnCtx<User>) => {
  return row.address;
};

const column = [
  {
    prop: "date",
    label: "Date",
    width: 120,
    sortable: true,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    formatter,
  },
];

const tableData: User[] = [
  {
    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>
<template>
  <el-table-next
    :data="tableData"
    :column="column"
    :default-sort="{ prop: 'date', order: 'descending' }"
    style="width: 100%"
  ></el-table-next>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface User {
  date: string;
  name: string;
  address: string;
}
const formatter = (row: User, column: TableColumnCtx<User>) => {
  return row.address;
};

const column = [
  {
    prop: "date",
    label: "Date",
    width: 120,
    sortable: true,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    formatter,
  },
];

const tableData: User[] = [
  {
    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>
展开代码
Copy

筛选

对表格进行筛选,可快速查找到自己想看的数据。

在列中设置 filtersfilter-method 属性即可开启该列的筛选, filters 是一个数组,filter-method 是一个方法,它用于决定某些数据是否显示, 会传入三个参数:value, rowcolumn

<template>
  <el-button @click="resetDateFilter">reset date filter</el-button>
  <el-button @click="clearFilter">reset all filters</el-button>
  <el-table-next
    :column="column"
    ref="tableRef"
    row-key="date"
    :data="tableData"
    style="width: 100%"
  >
    <template #default="scope">
      <el-tag :type="scope.row.tag === 'Home' ? '' : 'success'" disable-transitions>
        {{ scope.row.tag }}
      </el-tag>
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
import type { ElTable } from "element-plus";

interface User {
  date: string;
  name: string;
  address: string;
  tag: string;
}

const tableRef = ref<InstanceType<typeof ElTable>>();

const resetDateFilter = () => {
  tableRef.value!.clearFilter(["date"]);
};
// TODO: improvement typing when refactor table
const clearFilter = () => {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  tableRef.value!.clearFilter();
};
const formatter = (row: User, column: TableColumnCtx<User>) => {
  return row.address;
};
const filterTag = (value: string, row: User) => {
  return row.tag === value;
};
const filterHandler = (value: string, row: User, column: TableColumnCtx<User>) => {
  const property = column["property"];
  return row[property] === value;
};

const column = [
  {
    type: "index",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    sortable: true,
    width: 180,
    "column-key": "date",
    filters: [
      { text: "2016-05-01", value: "2016-05-01" },
      { text: "2016-05-02", value: "2016-05-02" },
      { text: "2016-05-03", value: "2016-05-03" },
      { text: "2016-05-04", value: "2016-05-04" },
    ],
    "filter-method": filterHandler,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    formatter,
  },
  {
    prop: "tag",
    label: "Tag",
    filters: [
      { text: "Home", value: "Home" },
      { text: "Office", value: "Office" },
    ],
    "filter-method": filterTag,
    "filter-placement": "bottom-end",
    slotName: "default",
  },
];

const tableData: User[] = [
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Office",
  },
];
</script>
<template>
  <el-button @click="resetDateFilter">reset date filter</el-button>
  <el-button @click="clearFilter">reset all filters</el-button>
  <el-table-next
    :column="column"
    ref="tableRef"
    row-key="date"
    :data="tableData"
    style="width: 100%"
  >
    <template #default="scope">
      <el-tag :type="scope.row.tag === 'Home' ? '' : 'success'" disable-transitions>
        {{ scope.row.tag }}
      </el-tag>
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
import type { ElTable } from "element-plus";

interface User {
  date: string;
  name: string;
  address: string;
  tag: string;
}

const tableRef = ref<InstanceType<typeof ElTable>>();

const resetDateFilter = () => {
  tableRef.value!.clearFilter(["date"]);
};
// TODO: improvement typing when refactor table
const clearFilter = () => {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  tableRef.value!.clearFilter();
};
const formatter = (row: User, column: TableColumnCtx<User>) => {
  return row.address;
};
const filterTag = (value: string, row: User) => {
  return row.tag === value;
};
const filterHandler = (value: string, row: User, column: TableColumnCtx<User>) => {
  const property = column["property"];
  return row[property] === value;
};

const column = [
  {
    type: "index",
    width: 50,
  },
  {
    prop: "date",
    label: "Date",
    sortable: true,
    width: 180,
    "column-key": "date",
    filters: [
      { text: "2016-05-01", value: "2016-05-01" },
      { text: "2016-05-02", value: "2016-05-02" },
      { text: "2016-05-03", value: "2016-05-03" },
      { text: "2016-05-04", value: "2016-05-04" },
    ],
    "filter-method": filterHandler,
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
    formatter,
  },
  {
    prop: "tag",
    label: "Tag",
    filters: [
      { text: "Home", value: "Home" },
      { text: "Office", value: "Office" },
    ],
    "filter-method": filterTag,
    "filter-placement": "bottom-end",
    slotName: "default",
  },
];

const tableData: User[] = [
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
    tag: "Office",
  },
];
</script>
展开代码
Copy

自定义列模板

自定义列的显示内容,可组合其他组件使用。

通过 slot 可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据,用法参考 demo。

<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%">
    <template #date="scope">
      <div style="display: flex; align-items: center">
        <el-icon>
          <timer />
        </el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </div>
    </template>
    <template #name="scope">
      <el-popover effect="light" trigger="hover" placement="top" width="auto">
        <template #default>
          <div>name: {{ scope.row.name }}</div>
          <div>address: {{ scope.row.address }}</div>
        </template>
        <template #reference>
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
      </el-popover>
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { Timer } from "@element-plus/icons-vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    prop: "address",
    label: "Operations",
    slotName: "default",
  },
];

const tableData: User[] = [
  {
    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>
<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%">
    <template #date="scope">
      <div style="display: flex; align-items: center">
        <el-icon>
          <timer />
        </el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </div>
    </template>
    <template #name="scope">
      <el-popover effect="light" trigger="hover" placement="top" width="auto">
        <template #default>
          <div>name: {{ scope.row.name }}</div>
          <div>address: {{ scope.row.address }}</div>
        </template>
        <template #reference>
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
      </el-popover>
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { Timer } from "@element-plus/icons-vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    prop: "address",
    label: "Operations",
    slotName: "default",
  },
];

const tableData: User[] = [
  {
    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>
展开代码
Copy

自定义表头

表头支持自定义。

通过设置 slot 来自定义表头。

<template>
  <el-table-next :column="column" :data="filterTableData" style="width: 100%">
    <template #header>
      <el-input v-model="search" size="small" placeholder="Type to search" />
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { ref, computed } from "vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const search = ref("");
const filterTableData = computed(() =>
  tableData.filter(
    (data) =>
      !search.value || data.name.toLowerCase().includes(search.value.toLowerCase())
  )
);
const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    align: "right",
    slotName: "default",
    headerSlot: "header",
  },
];

const tableData: User[] = [
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-02",
    name: "John",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-04",
    name: "Morgan",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Jessy",
    address: "No. 189, Grove St, Los Angeles",
  },
];
</script>
<template>
  <el-table-next :column="column" :data="filterTableData" style="width: 100%">
    <template #header>
      <el-input v-model="search" size="small" placeholder="Type to search" />
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
import { ref, computed } from "vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const search = ref("");
const filterTableData = computed(() =>
  tableData.filter(
    (data) =>
      !search.value || data.name.toLowerCase().includes(search.value.toLowerCase())
  )
);
const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    align: "right",
    slotName: "default",
    headerSlot: "header",
  },
];

const tableData: User[] = [
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-02",
    name: "John",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-04",
    name: "Morgan",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Jessy",
    address: "No. 189, Grove St, Los Angeles",
  },
];
</script>
展开代码
Copy

展开行

当行内容过多并且不想显示横向滚动条时,可以使用 Table 展开行功能。

通过设置 type="expand" 和 slot 可以开启展开行功能, el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 slot 相同。

<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%">
    <template #default="props">
      <p>State: {{ props.row.state }}</p>
      <p>City: {{ props.row.city }}</p>
      <p>Address: {{ props.row.address }}</p>
      <p>Zip: {{ props.row.zip }}</p>
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
const column = [
  {
    type: "expand",
    slotName: "default",
  },
  {
    label: "Date",
    prop: "date",
  },
  {
    label: "Name",
    prop: "name",
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%">
    <template #default="props">
      <p>State: {{ props.row.state }}</p>
      <p>City: {{ props.row.city }}</p>
      <p>Address: {{ props.row.address }}</p>
      <p>Zip: {{ props.row.zip }}</p>
    </template>
  </el-table-next>
</template>

<script lang="ts" setup>
const column = [
  {
    type: "expand",
    slotName: "default",
  },
  {
    label: "Date",
    prop: "date",
  },
  {
    label: "Name",
    prop: "name",
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-08",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-06",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
  {
    date: "2016-05-07",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
  },
];
</script>
展开代码
Copy

树形数据与懒加载

支持树类型的数据的显示。 当 row 中包含 children 字段时,被视为树形数据。 渲染树形数据时,必须要指定 row-key。支持子节点数据异步加载。 设置 Table 的 lazy 属性为 true 与加载函数 load 。 通过指定 row 中的 hasChildren 字段来指定哪些行是包含子节点。 childrenhasChildren 都可以通过 tree-props 配置。

<template>
  <div>
    <el-table-next
      :column="column"
      :data="tableData"
      style="width: 100%; margin-bottom: 20px"
      row-key="id"
      border
      default-expand-all
    ></el-table-next>

    <el-table-next
      :column="column2"
      :data="tableData1"
      style="width: 100%"
      row-key="id"
      border
      lazy
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
    </el-table-next>
  </div>
</template>
<script lang="ts" setup>
interface User {
  id: number;
  date: string;
  name: string;
  hasChildren?: boolean;
  children?: User[];
}

const load = (row: User, treeNode: unknown, resolve: (date: User[]) => void) => {
  setTimeout(() => {
    resolve([
      {
        id: 31,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
      {
        id: 32,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
    ]);
  }, 1000);
};
const column = [
  {
    label: "Date",
    prop: "date",
    sortable: true,
    width: 180,
  },
  {
    label: "Name",
    prop: "name",
    sortable: true,
    width: 180,
  },
];
const column2 = [
  {
    label: "Date",
    prop: "date",
    width: 180,
  },
  {
    label: "Name",
    prop: "name",
    width: 180,
  },
];
const tableData: User[] = [
  {
    id: 1,
    date: "2016-05-02",
    name: "wangxiaohu",
  },
  {
    id: 2,
    date: "2016-05-04",
    name: "wangxiaohu",
  },
  {
    id: 3,
    date: "2016-05-01",
    name: "wangxiaohu",
    children: [
      {
        id: 31,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
      {
        id: 32,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
    ],
  },
  {
    id: 4,
    date: "2016-05-03",
    name: "wangxiaohu",
  },
];

const tableData1: User[] = [
  {
    id: 1,
    date: "2016-05-02",
    name: "wangxiaohu",
  },
  {
    id: 2,
    date: "2016-05-04",
    name: "wangxiaohu",
  },
  {
    id: 3,
    date: "2016-05-01",
    name: "wangxiaohu",
    hasChildren: true,
  },
  {
    id: 4,
    date: "2016-05-03",
    name: "wangxiaohu",
  },
];
</script>
<template>
  <div>
    <el-table-next
      :column="column"
      :data="tableData"
      style="width: 100%; margin-bottom: 20px"
      row-key="id"
      border
      default-expand-all
    ></el-table-next>

    <el-table-next
      :column="column2"
      :data="tableData1"
      style="width: 100%"
      row-key="id"
      border
      lazy
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
    </el-table-next>
  </div>
</template>
<script lang="ts" setup>
interface User {
  id: number;
  date: string;
  name: string;
  hasChildren?: boolean;
  children?: User[];
}

const load = (row: User, treeNode: unknown, resolve: (date: User[]) => void) => {
  setTimeout(() => {
    resolve([
      {
        id: 31,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
      {
        id: 32,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
    ]);
  }, 1000);
};
const column = [
  {
    label: "Date",
    prop: "date",
    sortable: true,
    width: 180,
  },
  {
    label: "Name",
    prop: "name",
    sortable: true,
    width: 180,
  },
];
const column2 = [
  {
    label: "Date",
    prop: "date",
    width: 180,
  },
  {
    label: "Name",
    prop: "name",
    width: 180,
  },
];
const tableData: User[] = [
  {
    id: 1,
    date: "2016-05-02",
    name: "wangxiaohu",
  },
  {
    id: 2,
    date: "2016-05-04",
    name: "wangxiaohu",
  },
  {
    id: 3,
    date: "2016-05-01",
    name: "wangxiaohu",
    children: [
      {
        id: 31,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
      {
        id: 32,
        date: "2016-05-01",
        name: "wangxiaohu",
      },
    ],
  },
  {
    id: 4,
    date: "2016-05-03",
    name: "wangxiaohu",
  },
];

const tableData1: User[] = [
  {
    id: 1,
    date: "2016-05-02",
    name: "wangxiaohu",
  },
  {
    id: 2,
    date: "2016-05-04",
    name: "wangxiaohu",
  },
  {
    id: 3,
    date: "2016-05-01",
    name: "wangxiaohu",
    hasChildren: true,
  },
  {
    id: 4,
    date: "2016-05-03",
    name: "wangxiaohu",
  },
];
</script>
展开代码
Copy

表尾合计行

若表格展示的是各类数字,可以在表尾显示各列的合计。

show-summary 设置为true就会在表格尾部展示合计行。 默认情况下,对于合计行,第一列不进行数据求合操作,而是显示「合计」二字(可通过sum-text配置),其余列会将本列所有数值进行求合操作,并显示出来。 当然,你也可以定义自己的合计逻辑。 使用 summary-method 并传入一个方法,返回一个数组,这个数组中的各项就会显示在合计行的各列中, 具体可以参考本例中的第二个表格。

<template>
  <el-table-next
    :column="column"
    :data="tableData"
    border
    show-summary
    style="width: 100%"
  ></el-table-next>

  <el-table-next
    :column="column2"
    :data="tableData"
    border
    height="200"
    :summary-method="getSummaries"
    show-summary
    style="width: 100%; margin-top: 20px"
  ></el-table-next>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface Product {
  id: string;
  name: string;
  amount1: string;
  amount2: string;
  amount3: number;
}

interface SummaryMethodProps<T = Product> {
  columns: TableColumnCtx<T>[];
  data: T[];
}

const getSummaries = (param: SummaryMethodProps) => {
  const { columns, data } = param;
  const sums: string[] = [];
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = "Total Cost";
      return;
    }
    const values = data.map((item) => Number(item[column.property]));
    if (!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)}`;
    } else {
      sums[index] = "N/A";
    }
  });

  return sums;
};

const column = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const column2 = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Cost 1 ($)",
    prop: "amount1",
  },
  {
    label: "Cost 2 ($)",
    prop: "amount2",
  },
  {
    label: "Cost 3 ($)",
    prop: "amount3",
  },
];

const tableData: Product[] = [
  {
    id: "12987122",
    name: "Tom",
    amount1: "234",
    amount2: "3.2",
    amount3: 10,
  },
  {
    id: "12987123",
    name: "Tom",
    amount1: "165",
    amount2: "4.43",
    amount3: 12,
  },
  {
    id: "12987124",
    name: "Tom",
    amount1: "324",
    amount2: "1.9",
    amount3: 9,
  },
  {
    id: "12987125",
    name: "Tom",
    amount1: "621",
    amount2: "2.2",
    amount3: 17,
  },
  {
    id: "12987126",
    name: "Tom",
    amount1: "539",
    amount2: "4.1",
    amount3: 15,
  },
];
</script>
<template>
  <el-table-next
    :column="column"
    :data="tableData"
    border
    show-summary
    style="width: 100%"
  ></el-table-next>

  <el-table-next
    :column="column2"
    :data="tableData"
    border
    height="200"
    :summary-method="getSummaries"
    show-summary
    style="width: 100%; margin-top: 20px"
  ></el-table-next>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface Product {
  id: string;
  name: string;
  amount1: string;
  amount2: string;
  amount3: number;
}

interface SummaryMethodProps<T = Product> {
  columns: TableColumnCtx<T>[];
  data: T[];
}

const getSummaries = (param: SummaryMethodProps) => {
  const { columns, data } = param;
  const sums: string[] = [];
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = "Total Cost";
      return;
    }
    const values = data.map((item) => Number(item[column.property]));
    if (!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)}`;
    } else {
      sums[index] = "N/A";
    }
  });

  return sums;
};

const column = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const column2 = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Cost 1 ($)",
    prop: "amount1",
  },
  {
    label: "Cost 2 ($)",
    prop: "amount2",
  },
  {
    label: "Cost 3 ($)",
    prop: "amount3",
  },
];

const tableData: Product[] = [
  {
    id: "12987122",
    name: "Tom",
    amount1: "234",
    amount2: "3.2",
    amount3: 10,
  },
  {
    id: "12987123",
    name: "Tom",
    amount1: "165",
    amount2: "4.43",
    amount3: 12,
  },
  {
    id: "12987124",
    name: "Tom",
    amount1: "324",
    amount2: "1.9",
    amount3: 9,
  },
  {
    id: "12987125",
    name: "Tom",
    amount1: "621",
    amount2: "2.2",
    amount3: 17,
  },
  {
    id: "12987126",
    name: "Tom",
    amount1: "539",
    amount2: "4.1",
    amount3: 15,
  },
];
</script>
展开代码
Copy

合并行或列

多行或多列共用一个数据时,可以合并行或列。

通过给 table 传入span-method方法可以实现合并行或列, 方法的参数是一个对象,里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组,第一个元素代表 rowspan,第二个元素代表 colspan。 也可以返回一个键名为 rowspancolspan 的对象。

<template>
  <div>
    <el-table-next
      :column="column"
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%"
    ></el-table-next>

    <el-table-next
      :column="column2"
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px"
    ></el-table-next>
  </div>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface User {
  id: string;
  name: string;
  amount1: string;
  amount2: string;
  amount3: number;
}

interface SpanMethodProps {
  row: User;
  column: TableColumnCtx<User>;
  rowIndex: number;
  columnIndex: number;
}

const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
  if (rowIndex % 2 === 0) {
    if (columnIndex === 0) {
      return [1, 2];
    } else if (columnIndex === 1) {
      return [0, 0];
    }
  }
};

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
  if (columnIndex === 0) {
    if (rowIndex % 2 === 0) {
      return {
        rowspan: 2,
        colspan: 1,
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      };
    }
  }
};

const column = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const column2 = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const tableData: User[] = [
  {
    id: "12987122",
    name: "Tom",
    amount1: "234",
    amount2: "3.2",
    amount3: 10,
  },
  {
    id: "12987123",
    name: "Tom",
    amount1: "165",
    amount2: "4.43",
    amount3: 12,
  },
  {
    id: "12987124",
    name: "Tom",
    amount1: "324",
    amount2: "1.9",
    amount3: 9,
  },
  {
    id: "12987125",
    name: "Tom",
    amount1: "621",
    amount2: "2.2",
    amount3: 17,
  },
  {
    id: "12987126",
    name: "Tom",
    amount1: "539",
    amount2: "4.1",
    amount3: 15,
  },
];
</script>
<template>
  <div>
    <el-table-next
      :column="column"
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%"
    ></el-table-next>

    <el-table-next
      :column="column2"
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px"
    ></el-table-next>
  </div>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";

interface User {
  id: string;
  name: string;
  amount1: string;
  amount2: string;
  amount3: number;
}

interface SpanMethodProps {
  row: User;
  column: TableColumnCtx<User>;
  rowIndex: number;
  columnIndex: number;
}

const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
  if (rowIndex % 2 === 0) {
    if (columnIndex === 0) {
      return [1, 2];
    } else if (columnIndex === 1) {
      return [0, 0];
    }
  }
};

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
  if (columnIndex === 0) {
    if (rowIndex % 2 === 0) {
      return {
        rowspan: 2,
        colspan: 1,
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      };
    }
  }
};

const column = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const column2 = [
  {
    label: "ID",
    width: 180,
    prop: "id",
  },
  {
    label: "Name",
    prop: "name",
  },
  {
    label: "Amount 1",
    prop: "amount1",
    sortable: true,
  },
  {
    label: "Amount 2",
    prop: "amount2",
    sortable: true,
  },
  {
    label: "Amount 3",
    prop: "amount3",
    sortable: true,
  },
];

const tableData: User[] = [
  {
    id: "12987122",
    name: "Tom",
    amount1: "234",
    amount2: "3.2",
    amount3: 10,
  },
  {
    id: "12987123",
    name: "Tom",
    amount1: "165",
    amount2: "4.43",
    amount3: 12,
  },
  {
    id: "12987124",
    name: "Tom",
    amount1: "324",
    amount2: "1.9",
    amount3: 9,
  },
  {
    id: "12987125",
    name: "Tom",
    amount1: "621",
    amount2: "2.2",
    amount3: 17,
  },
  {
    id: "12987126",
    name: "Tom",
    amount1: "539",
    amount2: "4.1",
    amount3: 15,
  },
];
</script>
展开代码
Copy

自定义索引

自定义 type=index 列的行号。

通过给 type=index 的列传入 index 属性,可以自定义索引。 该属性传入数字时,将作为索引的起始值。 也可以传入一个方法,它提供当前行的行号(从 0 开始)作为参数,返回值将作为索引展示。

<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%"></el-table-next>
</template>

<script lang="ts" setup>
const indexMethod = (index: number) => {
  return index * 2;
};
const column = [
  {
    type: "index",
    index: indexMethod,
  },
  {
    prop: "date",
    label: "Date",
    width: 180,
  },
  {
    prop: "name",
    label: "Name",
    width: 180,
  },
  {
    prop: "address",
    label: "Address",
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
];
</script>
<template>
  <el-table-next :column="column" :data="tableData" style="width: 100%"></el-table-next>
</template>

<script lang="ts" setup>
const indexMethod = (index: number) => {
  return index * 2;
};
const column = [
  {
    type: "index",
    index: indexMethod,
  },
  {
    prop: "date",
    label: "Date",
    width: 180,
  },
  {
    prop: "name",
    label: "Name",
    width: 180,
  },
  {
    prop: "address",
    label: "Address",
  },
];
const tableData = [
  {
    date: "2016-05-03",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Home",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    state: "California",
    city: "Los Angeles",
    address: "No. 189, Grove St, Los Angeles",
    zip: "CA 90036",
    tag: "Office",
  },
];
</script>
展开代码
Copy

Table Layout

The table-layout property sets the algorithm used to lay out table cells, rows, and columns.

<template>
  <el-radio-group v-model="tableLayout">
    <el-radio-button label="fixed"></el-radio-button>
    <el-radio-button label="auto"></el-radio-button>
  </el-radio-group>
  <el-table-next
    :column="column"
    :data="tableData"
    :table-layout="tableLayout"
  ></el-table-next>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const tableLayout = ref<"fixed" | "auto">("fixed");

const column = [
  {
    prop: "date",
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
  },
  {
    prop: "address",
    label: "Address",
  },
];

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>
<template>
  <el-radio-group v-model="tableLayout">
    <el-radio-button label="fixed"></el-radio-button>
    <el-radio-button label="auto"></el-radio-button>
  </el-radio-group>
  <el-table-next
    :column="column"
    :data="tableData"
    :table-layout="tableLayout"
  ></el-table-next>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const tableLayout = ref<"fixed" | "auto">("fixed");

const column = [
  {
    prop: "date",
    label: "Date",
  },
  {
    prop: "name",
    label: "Name",
  },
  {
    prop: "address",
    label: "Address",
  },
];

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>
展开代码
Copy

示例 has loaded