# Table 表格组件

基于 ElementUI el-table 封装,支持通过配置数组渲染表格列(支持多级表头),内置分页组件。

# 基础用法

hide code
<template>

  <div>
    <ctc-table
      :data="tableData"
      :column="columns"
    >
      <!-- 自定义列插槽 -->
      <template #status="{ row }">
        <el-tag :type="row.status === 1 ? 'success' : 'danger'">
          {{ row.status === 1 ? "启用" : "禁用" }}
        </el-tag>
      </template>
      <!-- 操作列 -->
      <template #action="{ row }">
        <el-button type="text" @click="handleEdit(row)">编辑</el-button>
      </template>
    </ctc-table>
  </div>
</template>
<script>
export default {
  data() {
    return {
      tableData: [
        { name: '张三', age: 18, status: 1 },
        { name: '李四', age: 25, status: 0 },
        { name: '王五', age: 30, status: 1 }
      ],
      total: 3,
      currentPage: 1,
      pageSize: 10,
      columns: [
        { label: "姓名", prop: "name" },
        { label: "年龄", prop: "age" },
        { label: "状态", prop: "status" },
        { label: "操作", prop: "action", width: 200 },
      ],
    };
  }
};
</script>

# 属性 (Props)

参数 说明 类型 默认值
data 显示的数据 Array []
column 表格列配置数组 (见下文) Array []
pagination 是否显示分页 Boolean false
total 总条目数 (用于分页) Number 0
currentPage 当前页码 (支持 .sync 修饰符) Number -
pageSize 每页显示条目个数 (支持 .sync 修饰符) Number -
pageStyle 分页样式 Object/String -
merge 需要合并的列字段数组 (如 ['name', 'type']) Array -
spanMethod 合并行或列的计算方法 (同 el-table) Function -
autoHeight 是否自动适应父容器高度 Boolean true
loading 加载状态 Boolean false
draggable 是否开启行拖拽 Boolean false

透传属性: 支持 el-table 的所有属性 (如 height, stripe, border 等)。

# 事件 (Events)

事件名 说明 参数
current-change
(或 currentChange)
分页 - 当前页改变时触发 currentPage
update:currentPage 分页 - 当前页同步更新 currentPage
size-change
(或 sizeChange)
分页 - 每页条数改变时触发 pageSize
update:pageSize 分页 - 每页条数同步更新 pageSize
prev-click
(或 prevClick)
分页 - 点击上一页 currentPage
next-click
(或 nextClick)
分页 - 点击下一页 currentPage
drag-end 拖拽结束时触发 { oldIndex, newIndex, row }

透传事件: 支持 el-table 的所有事件 (如 sort-change, selection-change 等)。

注:为了向后兼容,分页相关的事件同时支持短横线(官方推荐)和驼峰命名(如 @current-change@currentChange 均可触发)。对于数据双向绑定,推荐使用 .sync 修饰符(如 :current-page.sync="page.current")。

# Column 配置对象

column 数组中的每个对象支持以下属性:

属性 说明 类型
label 显示的标题 String
prop 对应列内容的字段名 (也作为插槽名) String
width 列宽度 String
minWidth 最小列宽 String
fixed 列是否固定 (true, left, right) Boolean/String
sortable 对应列是否可以排序 Boolean
align 对齐方式 (left/center/right) String
headerAlign 表头对齐方式 String
children 多级表头上配置 (嵌套 Column 对象) Array
formatter 格式化内容 function(row, column, cellValue, index) Function
renderHeader 自定义表头渲染函数 (JSX) Function
slotHeader 自定义表头插槽名 (在 template 中使用该名称定义插槽) String
slotBody 自定义列内容插槽名 (默认使用 prop 值作为插槽名) String

| labelClassName | 标签的类名 | String | | columnKey | 对应列的唯一标识 (用于解决 prop 重复时的 key 冲突) | String |

透传属性: 支持 el-table-column 的所有属性 (如 className, show-overflow-tooltip 等),将直接透传给组件。

注意:prop 既是数据字段,也是自定义插槽的名称。如果在 ctc-table 内部写了 <template #xxx="scope">,则会优先使用插槽渲染该列。当多个列使用相同的 prop 时,请务必设置唯一的 columnKey 以避免 Vue 的 key 冲突告警。

# 插槽 (Slots)

插槽名 说明
[column.prop] 动态列插槽,名称对应 column 配置中的 prop
[column.slotHeader] 动态表头插槽,名称对应 column 配置中的 slotHeader
append 插入至表格最后一行之后的内容
empty 空数据时显示的文本内容
pagination 分页组件内部自定义插槽

# 插槽作用域参数

列插槽和表头插槽除了 Element UI 原有的作用域参数外,还额外提供了 config 属性,指向你在 column 数组中定义的原始配置对象,可通过它访问自定义属性。

参数 说明
row 当前行数据 (仅列插槽)
column Element UI 内部的 column 对象 (仅含标准属性)
$index 当前行索引 (仅列插槽)
config 你定义的原始 column 配置对象,可访问自定义属性如 config.unit

# 自定义表头插槽 (slotHeader)

通过 slotHeader 可以在 template 中自定义表头内容,而无需编写 JSX。插槽作用域中的 config 指向原始的 column 配置对象,可以在其中维护自定义属性。

hide code
<template>
<ctc-table
      :data="tableData"
      :column="columns"
    >
<template #header-unit="{ config }">
<el-radio-group v-model="config.unit" size="mini">
<el-radio label="1">mg/m³</el-radio>
<el-radio label="2">g/m³</el-radio>
</el-radio-group>
</template>
<template #status="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
{{ row.status === 1 ? "启用" : "禁用" }}
</el-tag>
</template>
</ctc-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        { name: '张三', age: 18, status: 1 },
        { name: '李四', age: 25, status: 0 },
        { name: '王五', age: 30, status: 1 }
      ],
      columns: [
        { label: "姓名", prop: "name" },
        { label: "年龄", prop: "age" },
        { label: "状态", prop: "status" },
        { label: "单位", prop: "unit", slotHeader: "header-unit", unit: "1" },
      ],
    };
  },
};
</script>

# 行拖拽 (Row Dragging)

通过设置 draggable 属性为 true 开启行拖拽功能。拖拽结束时会触发 drag-end 事件,返回被拖拽行的索引信息。

hide code
<template>

  <div>
    <ctc-table
      draggable
      :data="tableData"
      :column="columns"
      :total="0"
      @drag-end="handleDragEnd"
    >
    </ctc-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        { id: 1, name: '张三', date: '2023-01-01', address: '上海市普陀区金沙江路 1518 弄' },
        { id: 2, name: '李四', date: '2023-01-02', address: '上海市普陀区金沙江路 1517 弄' },
        { id: 3, name: '王五', date: '2023-01-03', address: '上海市普陀区金沙江路 1519 弄' },
        { id: 4, name: '赵六', date: '2023-01-04', address: '上海市普陀区金沙江路 1516 弄' }
      ],
      columns: [
        { label: "ID", prop: "id", width: 80 },
        { label: "日期", prop: "date" },
        { label: "姓名", prop: "name" },
        { label: "地址", prop: "address" },
      ],
    };
  },
  methods: {
    handleDragEnd({ oldIndex, newIndex, row }) {
      console.log('拖拽结束:', oldIndex, newIndex, row)
      // 交换数据 (简单实现)
      const targetRow = this.tableData.splice(oldIndex, 1)[0]
      this.tableData.splice(newIndex, 0, targetRow)
      this.$message.success(`行从 ${oldIndex} 拖拽到 ${newIndex}`)
    }
  }
};
</script>
Last Updated: 2/27/2026, 5:13:26 PM