一、前言
在使用 Element Plus(或 Element UI)构建管理后台时,<el-table>
是最常见的组件之一。
无论是渲染列表、订单数据、监控日志、还是可视化报表,都离不开它。
但在复杂场景中,我们经常会遇到这样的需求:
- ✅ 只给某一列的单元格添加特殊颜色;
- ✅ 根据某个值动态调整字体或背景;
- ✅ 对特定条件的行或列设置警告样式;
- ✅ 自定义 hover 效果、边框或图标。
此时,cell-style
函数属性就是核心入口。
它能让我们对每一个单元格实现精确的样式控制。
二、基本原理概览
<el-table>
提供了几个与样式相关的函数钩子属性:
属性名 | 作用 | 返回类型 |
---|---|---|
cell-style | 控制单元格样式 | 对象或函数返回对象 |
header-cell-style | 控制表头单元格样式 | 对象或函数返回对象 |
row-style | 控制整行样式 | 对象或函数返回对象 |
header-row-style | 控制表头整行样式 | 对象或函数返回对象 |
cell-class-name | 控制单元格 class 名称 | 函数返回字符串 |
cell-style
的调用机制:
cell-style({ row, column, rowIndex, columnIndex })
返回一个对象形式的 CSS 样式:
return {
color: 'red',
backgroundColor: '#fef0f0',
fontWeight: 'bold'
}
执行时机:
- 每次渲染表格时(初次或更新数据后)都会被触发;
- 每个单元格都会独立调用一次;
- 可根据 row/column 进行条件判断。
三、最小可运行示例
让我们从一个最小 Vue 示例开始。
示例1:基础用法
<template>
<el-table :data="tableData" :cell-style="setCellStyle" border style="width: 600px">
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="age" label="年龄" width="80" />
<el-table-column prop="score" label="成绩" width="100" />
</el-table>
</template>
<script setup>
import { ref } from 'vue'
const tableData = ref([
{ name: '张三', age: 18, score: 95 },
{ name: '李四', age: 22, score: 65 },
{ name: '王五', age: 25, score: 45 }
])
const setCellStyle = ({ row, column }) => {
if (column.property === 'score') {
if (row.score >= 90) {
return { backgroundColor: '#e1f3d8', color: '#67c23a' } // 优秀
} else if (row.score < 60) {
return { backgroundColor: '#fde2e2', color: '#f56c6c' } // 不及格
}
}
return {}
}
</script>
🟢 运行效果:
- 当成绩 ≥ 90 时,单元格变绿色;
- 当成绩 < 60 时,单元格变红;
- 其他情况保持默认。
四、cell-style 的函数参数详解
Element Plus 源码中,cell-style
的回调参数如下:
{
row, // 当前行数据
column, // 当前列信息(含 prop、label 等)
rowIndex, // 当前行索引
columnIndex // 当前列索引
}
参数说明表:
参数名 | 类型 | 说明 |
---|---|---|
row | Object | 当前行的完整数据对象 |
column | Object | 当前列的配置信息(含 prop, label 等) |
rowIndex | Number | 当前行的序号(从0开始) |
columnIndex | Number | 当前列的序号(从0开始) |
应用场景举例:
column.property
用来判断是哪一列;row.someField
用来判断该行的状态;rowIndex
可实现奇偶行样式;columnIndex
可实现首列或末列特殊样式。
五、图解执行流程
以下是 el-table
渲染过程中 cell-style
的调用流程:
┌──────────────────────────────┐
│ 渲染 el-table │
└───────────────┬──────────────┘
│
▼
每列渲染 el-table-column
│
▼
渲染每个单元格 <td> 内容
│
▼
调用 cell-style({ row, column, rowIndex, columnIndex })
│
▼
返回 style 对象 → 绑定到 <td> 的 style 属性
从源码角度看(简化版):
const style = getCellStyle({
row,
column,
rowIndex,
columnIndex
})
<td :style="style"> ... </td>
六、进阶实战:条件样式与动态计算
1️⃣ 条件样式 - 多列判断
const setCellStyle = ({ row, column }) => {
if (column.property === 'age' && row.age > 20) {
return { color: '#409EFF', fontWeight: 'bold' }
}
if (column.property === 'score' && row.score < 60) {
return { backgroundColor: '#fde2e2', color: '#f56c6c' }
}
}
🟩 要点:
可通过 column.property
精确判断是哪一列。
2️⃣ 奇偶行差异
const setCellStyle = ({ rowIndex }) => {
if (rowIndex % 2 === 0) {
return { backgroundColor: '#fafafa' }
}
}
可以搭配 row-style
做全行样式的统一控制。
3️⃣ 根据业务状态动态样式
假设我们有订单状态表:
<el-table :data="orders" :cell-style="orderCellStyle">
<el-table-column prop="orderId" label="订单号" />
<el-table-column prop="status" label="状态" />
</el-table>
const orderCellStyle = ({ row, column }) => {
if (column.property === 'status') {
switch (row.status) {
case '已支付':
return { color: '#67c23a', fontWeight: 'bold' }
case '未支付':
return { color: '#e6a23c' }
case '已取消':
return { color: '#909399', textDecoration: 'line-through' }
}
}
}
七、与 cell-class-name 的区别与配合
属性 | 返回类型 | 控制方式 | 使用场景 |
---|---|---|---|
cell-style | 对象 | 直接设置样式(style) | 简单样式、动态计算颜色 |
cell-class-name | 字符串 | 添加 class 名称 | 复用 CSS class 样式、更灵活控制 |
例如:
<el-table :cell-class-name="cellClassName">
...
</el-table>
const cellClassName = ({ column, row }) => {
if (column.property === 'status' && row.status === '异常') {
return 'danger-cell'
}
}
.danger-cell {
background-color: #fde2e2 !important;
color: #f56c6c !important;
}
✅ 推荐实践:
- 若样式为固定预定义样式,使用
cell-class-name
- 若样式随数值变化(如渐变、动态颜色),使用
cell-style
八、复杂表格案例:多条件动态高亮
假设我们有一个销售数据表:
姓名 | 地区 | 销售额 | 完成率 |
---|---|---|---|
张三 | 华东 | 120000 | 95% |
李四 | 华南 | 75000 | 70% |
王五 | 西北 | 35000 | 40% |
我们希望:
- 销售额低于 50000 → 红底;
- 完成率 > 90% → 绿色;
- 地区为 “华南” → 黄色高亮。
实现代码:
<template>
<el-table :data="sales" :cell-style="salesCellStyle" border>
<el-table-column prop="name" label="姓名" />
<el-table-column prop="region" label="地区" />
<el-table-column prop="sales" label="销售额" />
<el-table-column prop="rate" label="完成率" />
</el-table>
</template>
<script setup>
import { ref } from 'vue'
const sales = ref([
{ name: '张三', region: '华东', sales: 120000, rate: 95 },
{ name: '李四', region: '华南', sales: 75000, rate: 70 },
{ name: '王五', region: '西北', sales: 35000, rate: 40 }
])
const salesCellStyle = ({ row, column }) => {
if (column.property === 'sales' && row.sales < 50000) {
return { backgroundColor: '#fde2e2', color: '#f56c6c' }
}
if (column.property === 'rate' && row.rate > 90) {
return { backgroundColor: '#e1f3d8', color: '#67c23a' }
}
if (column.property === 'region' && row.region === '华南') {
return { backgroundColor: '#fdf6ec', color: '#e6a23c' }
}
}
</script>
九、结合动态主题与 CSS 变量
若你项目使用了 暗色模式/亮色模式切换,可以将样式与 CSS 变量结合。
:root {
--danger-bg: #fde2e2;
--danger-color: #f56c6c;
}
.dark {
--danger-bg: #5a3d3d;
--danger-color: #ff8c8c;
}
const setCellStyle = ({ row, column }) => {
if (column.property === 'score' && row.score < 60) {
return {
backgroundColor: 'var(--danger-bg)',
color: 'var(--danger-color)'
}
}
}
十、性能优化与注意事项
1️⃣ 尽量避免复杂计算
因为 cell-style
会在每次渲染时对每个单元格执行。
✅ 优化策略:
- 提前计算标记字段;
- 使用缓存或 computed 属性;
- 避免在函数内创建过多对象。
2️⃣ 合理使用 class 与 style 混合策略
对于大数据量表格(>5000行):
- 优先使用
cell-class-name
; cell-style
仅用于少量动态样式。
3️⃣ 不推荐直接操作 DOM
不要在 cell-style 内使用 DOM API 或 $refs
,这会破坏虚拟DOM渲染机制。
十一、工程实践总结
在企业级项目中,建议建立一个通用样式工具模块:
// table-style-utils.js
export const highlightByValue = ({ row, column, key, threshold, color }) => {
if (column.property === key && row[key] > threshold) {
return { color }
}
}
然后在多个表格中复用:
<el-table :cell-style="(ctx) => highlightByValue({ ...ctx, key: 'score', threshold: 90, color: '#67c23a' })" />
十二、结语
cell-style
虽小,却是 Element Plus 表格中最灵活的定制点之一。
通过本篇文章你已经学会:
- ✅ 理解
cell-style
的底层执行机制; - ✅ 灵活应用参数进行条件判断;
- ✅ 区分
cell-style
与cell-class-name
; - ✅ 构建多条件动态样式逻辑;
- ✅ 实现工程化样式管理与优化。
📘 附录:完整工程模板下载结构
vue-el-table-style-demo/
├── src/
│ ├── App.vue
│ ├── components/
│ │ └── ScoreTable.vue
│ └── utils/
│ └── table-style-utils.js
├── package.json
└── vite.config.js
其中 ScoreTable.vue
即本文的完整代码,可直接运行。
该示例完全兼容 Vue 3 + Element Plus。