一、 核心组成与基本结构
Element UI 的表格主要由以下几个核心部分构成:
<el-table>
: 表格的根容器,负责管理数据、选择、排序、分页集成等全局状态。<el-table-column>
: 定义表格的一列。表格的列结构由一个或多个<el-table-column>
组件定义。data
: 传递给<el-table>
的data
属性,是一个数组,数组中的每个对象代表表格中的一行数据。prop
:<el-table-column>
的prop
属性,指定该列显示data
数组中每个对象的哪个属性的值。label
:<el-table-column>
的label
属性,定义该列的标题。
最基础的示例:
<template><el-table :data="tableData" style="width: 100%"><el-table-column prop="date" label="日期" width="180"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column prop="address" label="地址"></el-table-column></el-table>
</template><script>
export default {data() {return {tableData: [{date: '2016-05-02',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '2016-05-04',name: '王小虎',address: '上海市普陀区金沙江路 1517 弄'}]}}
}
</script>
二、 <el-table>
详解 (根容器)
管理表格的整体行为和外观。
- 关键属性:
data
: 必填。绑定表格的数据源数组。height
/max-height
: 设置表格的高度。设置height
时,表格会固定高度,超出部分出现纵向滚动条。设置max-height
时,表格高度随内容变化,但不超过最大值。stripe
: 是否显示斑马纹(隔行变色)。border
: 是否显示纵向边框。fit
: 列的宽度是否自撑开。true
时,列宽会根据内容自动调整(可能不精确)。show-header
: 是否显示表头。highlight-current-row
: 是否要高亮当前鼠标悬停的行。current-row-key
: 高亮某一行的key
,需要设置row-key
。row-key
: 为数据行指定key
,在使用reserve-selection
,expand
,tree
等功能时非常重要,推荐始终设置。通常指向数据中唯一的字段(如id
)。empty-text
: 数据为空时显示的文本。default-expand-all
: 默认是否展开所有行(用于树形数据或展开行)。tooltip-effect
:hover
时el-tooltip
的效果。dark
/light
。row-style
: 行的 CSS 样式,可以是对象或返回对象的函数。cell-style
: 单元格的 CSS 样式,可以是对象或返回对象的函数。header-row-style
/header-cell-style
: 表头行/单元格的样式。row-class-name
/cell-class-name
: 为行/单元格添加自定义 class,可以是字符串或返回字符串的函数。
- 关键事件:
@select
: 当用户手动勾选数据行的 Checkbox 时触发。@select-all
: 当用户手动勾选全选 Checkbox 时触发。@selection-change
: 当选择项发生变化时触发。@cell-mouse-enter
/@cell-mouse-leave
: 单元格 hover 事件。@cell-click
/@cell-dblclick
: 单元格点击/双击事件。@row-click
/@row-dblclick
: 行点击/双击事件。@row-contextmenu
: 行右键菜单事件。@header-click
/@header-contextmenu
: 表头点击/右键菜单事件。@sort-change
: 当表格的排序条件发生变化时触发。@filter-change
: 当表格的筛选条件发生变化时触发。@current-change
: 当高亮行发生变化时触发。@expand-change
: 当行展开状态发生变化时触发。
三、 <el-table-column>
详解 (列定义)
定义表格的每一列,是表格功能的核心。
- 关键属性:
type
: 定义列的类型。这是最重要的属性之一。selection
: 渲染一个Checkbox
,用于多选。通常放在第一列。index
: 渲染一个索引列,显示行的序号(从 1 开始)。expand
: 渲染一个可展开的按钮(+/-),用于展开行显示额外内容。
prop
: 指定该列显示数据对象中的哪个属性的值。例如prop="name"
会显示row.name
。label
: 该列的标题。width
: 设置该列的宽度(像素值,如180
)。min-width
: 设置该列的最小宽度。当fit=true
时,列宽会自适应,但不会小于min-width
。fixed
: 列是否固定。true
/left
/right
。固定列在表格横向滚动时会固定在左侧或右侧。sortable
: 该列是否可排序。true
/custom
。custom
时需要监听@sort-change
事件自行处理排序逻辑(常用于服务端排序)。sort-method
: 自定义排序方法的函数。sort-by
: 数组或字符串,指定排序时依据的属性或计算函数。resizable
: 对应列是否可以通过拖动改变宽度。true
/false
。column-key
: 给列设置一个 key,用于@filter-change
事件的回调参数。align
: 列内容的对齐方式。left
/center
/right
。header-align
: 表头的对齐方式。left
/center
/right
。若不设置,则继承align
的值。show-overflow-tooltip
: 当内容过长被隐藏时是否显示 tooltip。formatter
: 用来格式化显示文本的函数。function(row, column, cellValue, index)
。filters
: 数据过滤的选项。数组格式,如[{ text: '2016-05-01', value: '2016-05-01' }]
。filter-placement
: 过滤弹出框的定位。top-start
/top-end
/bottom-start
等。filter-multiple
: 数据过滤的选项是否多选。filter-method
: 数据过滤使用的方法。function(value, row, column)
,返回true
表示显示,false
表示隐藏。filtered-value
: 设置的筛选条件,需要配合filter-method
使用。
- 插槽 (Slots):
- 默认插槽: 用于自定义列的内容。这是实现复杂列(如操作按钮、状态标签、自定义组件)的最主要方式。插槽作用域 (
slot-scope
) 提供了row
(当前行数据),column
(当前列对象),$index
(行索引)。 header
: 用于自定义表头的内容。
- 默认插槽: 用于自定义列的内容。这是实现复杂列(如操作按钮、状态标签、自定义组件)的最主要方式。插槽作用域 (
四、 常用功能详解
1. 多选 (Selection)
<el-table:data="tableData"@selection-change="handleSelectionChange"ref="multipleTable"
><!-- selection 列 --><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="name" label="姓名"></el-table-column><!-- ... -->
</el-table><script>
export default {methods: {handleSelectionChange(val) {this.multipleSelection = val; // val 是选中行的数据对象数组},toggleSelection(rows) {// 手动切换某行的选中状态if (rows) {rows.forEach(row => {this.$refs.multipleTable.toggleRowSelection(row);});} else {this.$refs.multipleTable.clearSelection();}}}
}
</script>
2. 排序 (Sorting)
<!-- 简单前端排序 -->
<el-table-column prop="date" label="日期" sortable width="180"></el-table-column><!-- 自定义排序 (服务端排序) -->
<el-table-columnprop="name"label="姓名"sortable="custom"@sort-change="handleSortChange"
></el-table-column><script>
export default {methods: {handleSortChange({ column, prop, order }) {// 根据 prop 和 order ('ascending', 'descending', null) 请求服务端数据console.log(`排序字段: ${prop}, 顺序: ${order}`);// fetchSortedData(prop, order);}}
}
</script>
3. 筛选 (Filtering)
<el-table-columnprop="tag"label="标签":filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]":filter-method="filterTag"filter-placement="bottom-end"
><template slot-scope="scope"><!-- 使用 el-tag 展示标签 --><el-tag :type="scope.row.tag === '家' ? 'primary' : 'success'" closeable>{{ scope.row.tag }}</el-tag></template>
</el-table-column><script>
export default {methods: {filterTag(value, row) {return row.tag === value;}}
}
</script>
4. 自定义列内容 (使用插槽)
这是最强大的功能,可以实现几乎任何复杂的单元格内容。
<el-table-column label="操作" width="180" fixed="right"><template slot-scope="scope"><el-button @click="handleEdit(scope.$index, scope.row)" size="mini">编辑</el-button><el-button @click="handleDelete(scope.$index, scope.row)" size="mini" type="danger">删除</el-button><!-- 条件渲染 --><el-button v-if="scope.row.status === 0" size="mini" @click="handleEnable(scope.row)">启用</el-button><el-button v-else size="mini" @click="handleDisable(scope.row)">禁用</el-button><!-- 使用 switch --><el-switchv-model="scope.row.enabled"active-color="#13ce66"inactive-color="#ff4949"@change="handleSwitchChange(scope.row)"></el-switch></template>
</el-table-column>
5. 展开行 (Expand)
<el-table:data="tableData"style="width: 100%":row-key="getRowKey" <!-- 重要:用于展开行 -->
><!-- expand 列 --><el-table-column type="expand" width="50"><template slot-scope="props"><p>详细信息: {{ props.row.detail }}</p><p>描述: {{ props.row.description }}</p><!-- 可以嵌套另一个表格 --><!-- <el-table :data="props.row.subData">...</el-table> --></template></el-table-column><el-table-column label="姓名" prop="name"></el-table-column><!-- ... -->
</el-table><script>
export default {methods: {getRowKey(row) {return row.id; // 返回唯一标识}}
}
</script>
6. 树形数据与懒加载
<el-table:data="tableData"style="width: 100%;margin-bottom: 20px;"row-key="id"borderdefault-expand-all:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
><el-table-column prop="name" label="名称" sortable></el-table-column><el-table-column prop="date" label="日期" sortable></el-table-column><el-table-column prop="address" label="地址"></el-table-column>
</el-table><!-- 懒加载 -->
<el-table:data="tableData"style="width: 100%"row-key="id"border:tree-props="{children: 'children', hasChildren: 'hasChildren'}":load="load"
><!-- ... -->
</el-table><script>
export default {methods: {load(tree, treeNode, resolve) {// 模拟异步加载setTimeout(() => {resolve([{ id: 31, name: '叶子', date: '2016-05-01', address: '上海市' },{ id: 32, name: '叶子2', date: '2016-05-01', address: '上海市' }]);}, 1000);}}
}
</script>
7. 跨行/跨列合并 (Span Method)
<el-table:data="tableData":span-method="arraySpanMethod"borderstyle="width: 100%"
><!-- ... -->
</el-table><script>
export default {methods: {arraySpanMethod({ row, column, rowIndex, columnIndex }) {// 合并第一列(姓名)中相同值的行if (columnIndex === 0) {if (rowIndex % 2 === 0) {return {rowspan: 2, // 跨两行colspan: 1 // 跨一列};} else {return {rowspan: 0, // 不显示colspan: 0};}}}}
}
</script>
五、 高级技巧与最佳实践
- 性能优化:
row-key
: 必须设置,尤其在数据量大或使用reserve-selection
,expand
时,能极大提升性能。height
/max-height
: 设置固定高度,避免表格过长导致页面卡顿。- 虚拟滚动: Element UI 原生不支持,但社区有第三方库(如
vue-virtual-scroll-list
)可以集成实现超大数据量的流畅滚动。
- 分页集成: 通常
<el-table>
与<el-pagination>
组件配合使用。<el-table>
显示当前页数据,<el-pagination>
控制页码,通过监听分页变化请求新数据。 - 自定义样式: 使用
row-style
,cell-style
,row-class-name
,cell-class-name
或 CSS 覆盖(注意类名)来自定义表格样式。 - 空状态: 使用
empty-text
或slot="empty"
插槽自定义空数据时的展示内容(如图片、提示语)。 - 可访问性: 确保表头清晰,使用
aria-*
属性(如果框架支持)。 - 响应式: 表格在小屏幕上可能需要横向滚动。考虑使用
min-width
和max-width
控制列宽,或在移动端使用其他布局(如卡片列表)。
总结
Element UI 的 <el-table>
组件功能极其丰富,从基础的数据展示到复杂的多选、排序、筛选、展开、树形结构、合并单元格等,几乎涵盖了后台管理系统的所有表格需求。掌握 <el-table-column>
的 type
, prop
, label
, slot
以及 <el-table>
的 data
, row-key
是使用它的基础。灵活运用插槽 (slot-scope
) 是实现复杂交互和自定义内容的关键。结合分页组件,可以构建出功能强大、用户体验良好的数据表格界面。