前言
众所周知,el-table的单选功能只要添加highlight-current-row属性即可实现,非常的方便。然而,element-plus: "2.7.2"单选功能只有高亮,没有单选图标列,这令人有些意外,毕竟单选图标列在项目中还是比较常用的,而且也会让界面显得更加直观,先上效果图。
从 element-plus 的 issues 来看,目前没有要提供默认单选图标列的计划,需要自己定制需求
因此,本文将简要介绍如何为 el-table 添加单选列图标,希望能为有类似需求的用户提供一些参考。
方案
可根据项目需求自行选择
1. 自定义单选图标
通过自定义table-column插槽定制选中和非选中图标,可轻松实现必选的功能,跟多选表格的复选框不同,单击选中行是不会取消选中状态的,如果需要取消选中可以使用tableRef的setCurrentRow函数
2. 多选改单选
多选表格的复选框具有取消选中的功能,所以使用复选框来实现可取消选中的单选表格会简单很多,只需要通过tableRef的toggleRowSelection函数来控制复选框选中状态即可,同时还要隐藏列表头的全选label
代码实现
方案1 自定义单选图标
实现思路:
- 通过
highlight-current-row和@current-change提供高亮提示和选中事件 - 给
tableData添加一个选中标识变量,通过v-if和v-else控制单选图标的选中状态。 - 触发选中事件时,更新该标识变量,从而实现单选图标的状态切换。
<template>
<el-table
:data="tableData"
+ highlight-current-row
+ @current-change="handleCurrentChange"
>
<!-- 自定义单选列 el-radio 可替换成定制的内容 -->
+ <el-table-column width="50">
+ <template #default="{ row }">
+ <el-radio v-if="row.radio" /> <!-- 选中图标 -->
+ <el-radio v-else value="" /> <!-- 非选中图标 -->
+ </template>
+ </el-table-column>
...
</el-table>
</template>
<script lang="ts" setup>
interface User { ... }
const tableData = ref<User[]>([])
// 1.在给 tableData 赋值时添加选中标识
axios(...).then(({ data: User[] }) => {
+ tableData.value = data.map(i => ({ ...i, radio: false }))
})
const currentRow = ref()
// 2.触发选中事件后更新标识
const handleCurrentChange = (val: User | undefined) => {
+ tableData.forEach(i => (i.radio = i?.id === val?.id))
currentRow.value = val
...
}
</script>
在上述代码中,我们添加了一个radio标识,如果需要剔除该标识可使用如下代码(非必须)
// 表格数据
const originTableData = computed(() => tableData.value.map(({ radio, ...obj }) => obj))
// 选中行
const originCurrentRow = computed(() => {
const { radio, ...obj } = currentRow.value
return obj
})
方案2 多选改单选
实现思路:
- 通过
type="selection"和@selection-change提供多选列和选中事件 - 通过
tableRef的toggleRowSelection函数控制勾选状态 - 通过
display: none隐藏全选label
<template>
<el-table
ref="tableRef"
:data="tableData"
@selection-change="handleSelectionChange"
>
<el-table-column
label-class-name="table-selection"
type="selection"
/>
</el-table>
</template>
<script lang="ts" setup>
import { ElTable } from "element-plus";
interface User { ... }
const tableData: User[] = [...]
const tableRef = ref<InstanceType<typeof ElTable>>();
const selected = ref<User | undefined>();
// 多选改单选
const handleSelectionChange = (rows: User[]) => {
// 记录当前选中行
selected.value = rows.at(-1);
// 清除上一次的选中行
if (rows.length > 1) {
tableRef.value.toggleRowSelection(rows[0], false);
}
// 当前选中行
if (rows.length === 1) { ... }
// 取消勾选
if (!rows.length) { ... }
};
</script>
<style scoped>
/* 隐藏全选勾选框 */
:deep(.table-selection label) {
display: none;
}
</style>
总结
实现代码和思路都比较简单,这里只是一个简单的参考,主要用于补充el-table没有提供的一般性单选图标列,可根据实际需求替换选中图标及交互,如果你有更好的实现方式也欢迎讨论。