elmenet-plus el-table 官方没提供单选图标列?添加两行js代码就能搞定

1,315 阅读3分钟

前言

众所周知,el-table的单选功能只要添加highlight-current-row属性即可实现,非常的方便。然而,element-plus: "2.7.2"单选功能只有高亮,没有单选图标列,这令人有些意外,毕竟单选图标列在项目中还是比较常用的,而且也会让界面显得更加直观,先上效果图。

image.png

从 element-plus 的 issues 来看,目前没有要提供默认单选图标列的计划,需要自己定制需求

image.png

因此,本文将简要介绍如何为 el-table 添加单选列图标,希望能为有类似需求的用户提供一些参考。

方案

可根据项目需求自行选择

1. 自定义单选图标

通过自定义table-column插槽定制选中和非选中图标,可轻松实现必选的功能,跟多选表格的复选框不同,单击选中行是不会取消选中状态的,如果需要取消选中可以使用tableRef的setCurrentRow函数

2. 多选改单选

多选表格的复选框具有取消选中的功能,所以使用复选框来实现可取消选中的单选表格会简单很多,只需要通过tableRef的toggleRowSelection函数来控制复选框选中状态即可,同时还要隐藏列表头的全选label

代码实现

方案1 自定义单选图标

实现思路:

  1. 通过highlight-current-row@current-change提供高亮提示和选中事件
  2. tableData 添加一个选中标识变量,通过 v-ifv-else控制单选图标的选中状态。
  3. 触发选中事件时,更新该标识变量,从而实现单选图标的状态切换。
<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 多选改单选

image.png

实现思路:

  1. 通过type="selection"@selection-change提供多选列和选中事件
  2. 通过tableReftoggleRowSelection函数控制勾选状态
  3. 通过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没有提供的一般性单选图标列,可根据实际需求替换选中图标及交互,如果你有更好的实现方式也欢迎讨论。