Vue3+Element Plus表格单选实现(点击行实现单选+勾选行中的复选框实现单选)

应用效果:

点击行实现单选,不能取消勾选

点击复选框实现单选,可以取消勾选

实例代码:ApplyImportDialog.vue

<script setup lang="ts">
/**
 * 子受理单对话框
 */
defineOptions({
  name: "ApplyImportDialog"
});

// 子受理单表格
const applyTable = ref();
// 子受理单表格选集
const applyTableSelection = ref<Apply[]>([]);
// 子受理单表格当前选择行
const applyTableCurrentRow = ref<Apply>();

// 点击表格的行,实现单选
const onApplyTableRowClick = (row: Apply, column: any) => {
  // 子受理单表格选集取消选中
  applyTableSelection.value.forEach((item) => {
    applyTable.value.toggleRowSelection(item, false);
  });
  // 选中行
  applyTable.value.toggleRowSelection(row, true);
  applyTableCurrentRow.value = row;
};

/**
 * 行复选框选中事件,当手动勾选某一行的 Checkbox 时触发
 * @param selection 当前选集的行数据
 * @param row 当前操作的行数据
 */
const handleSelect = (selection: Apply[], row: Apply) => {
  // 先将当前选择行数据设置为undefined,未选中状态,避免获取到上次选中的行数据
  applyTableCurrentRow.value = undefined;
  // 清空所有选择
  applyTable.value.clearSelection();
  // 如果勾选了这一行(即不是取消勾选),则重新选中当前行
  if (selection.includes(row)) {
    // 选中行
    applyTable.value.toggleRowSelection(row, true);
    applyTableCurrentRow.value = row;
    // 设置当前行为选中行并且高亮显示,前提需要表格属性设置 highlight-current-row
    applyTable.value.setCurrentRow(applyTableCurrentRow.value);
  }
};

// 获取子受理单表格勾选的行数据
const handleApplyTableSelectionChange = (newSelection: Apply[]) => {
  //获取勾选行数据
  applyTableSelection.value = newSelection;
};

// 设置子受理单表格表头列的类名,回调对象 dataObj 的数据结构 { row, column, rowIndex, columnIndex }
const handleHeaderCellClassName = (dataObj: any) => {
  // 隐藏表头的全选框,el-table中需要设置 :header-cell-class-name="handleHeaderCellClassName"
  // 通过设置类名hideCheckBox的样式实现,::v-deep .hideCheckBox .cell { visibility: hidden; }
  if (dataObj.columnIndex === 0) {
    return "hide-table-header-checkBox";
  }
};
</script>

<template>

        <el-table
          ref="applyTable"
          :data="applyTableData"
          v-loading="applyTableLoading"
          highlight-current-row
          :border="true"
          style="width: 100%; height: 475px"
          :row-style="{ height: '0px', margin: '0px', padding: '0px' }"
          @row-click="onApplyTableRowClick"
          @select="handleSelect"
          @selection-change="handleApplyTableSelectionChange"
          :header-cell-class-name="handleHeaderCellClassName">
          <el-table-column type="selection" width="40" />

</template>

<style scoped lang="scss">
// 隐藏表头的全选框,el-table中需要设置 :header-cell-class-name="handleHeaderCellClassName"
:deep(.hide-table-header-checkBox .cell) {
  visibility: hidden;
}
</style>

在 Vue3 + Element Plus 的 el-table 中,要实现点击行即可选中该行的复选框,可以通过结合 row-click 事件和 toggleRowSelection 方法来实现。下面是一个清晰的实现方案。

实现方案

以下是实现该功能的核心代码示例:

html

<template>
  <el-table
    ref="tableRef"
    :data="tableData"
    @row-click="handleRowClick"
    @selection-change="handleSelectionChange"
    style="width: 100%"
  >
    <el-table-column type="selection" width="55" />
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="age" label="年龄" />
    <!-- 其他列 -->
  </el-table>
</template>

<script setup>
import { ref } from 'vue'

// 表格引用
const tableRef = ref()
// 表格数据
const tableData = ref([
  // ...你的数据
])
// 选中的行数据
const selectedRows = ref([])

// 处理行点击事件
const handleRowClick = (row) => {
  // 切换当前行的选中状态:cite[4]:cite[7]
  tableRef.value.toggleRowSelection(row)
}

// 处理选中变化,更新 selectedRows
const handleSelectionChange = (val) => {
  selectedRows.value = val
}
</script>

🎯 实现单选模式

如果你希望实现单选(即每次只能选中一行),可以使用以下代码:

html

<template>
  <el-table
    ref="tableRef"
    :data="tableData"
    @row-click="handleRowClick"
    @selection-change="handleSelectionChange"
    style="width: 100%"
  >
    <el-table-column type="selection" width="55" />
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="age" label="年龄" />
  </el-table>
</template>

<script setup>
import { ref } from 'vue'

const tableRef = ref()
const tableData = ref([
  { id: 1, name: '张三', age: 30 },
  { id: 2, name: '李四', age: 25 },
  // 更多数据...
])
const selectedRows = ref([])

// 处理行点击事件 - 单选模式
const handleRowClick = (row) => {
  // 先清空所有选择:cite[6]
  tableRef.value.clearSelection()
  // 然后选中当前行:cite[6]
  tableRef.value.toggleRowSelection(row, true)
}

// 处理选中变化
const handleSelectionChange = (val) => {
  selectedRows.value = val
  // 单选模式下,确保只保留最后一个选中的项:cite[5]
  if (val.length > 1) {
    const lastSelected = val[val.length - 1]
    tableRef.value.clearSelection()
    tableRef.value.toggleRowSelection(lastSelected, true)
  }
}
</script>

💡 关键点说明

  1. row-click 事件:当表格行被点击时触发,用于处理行点击逻辑。

  2. toggleRowSelection 方法:用于切换某一行的选中状态。

  3. clearSelection 方法:在单选模式下用于清空所有已选项。

  4. selection-change 事件:当选中的行发生变化时触发,用于获取当前选中的行数据。

⚠️ 注意事项

  • 确保给 el-table 添加了 ref 属性,以便通过引用调用表格的方法。

  • 如果需要更精细的控制(例如根据条件禁止某些行被选中),可以在 toggleRowSelection 前添加判断逻辑。

  • 在单选模式下,你可能还需要处理表头的全选复选框,可以通过CSS隐藏它。


在 Vue3 + Element Plus 的 el-table 中,当启用复选框列 (type="selection") 时,表头默认会显示一个全选复选框。在单选模式下,这个全选按钮通常不符合需求,需要隐藏。以下是几种隐藏表头全选复选框的方法:

方法一:使用 CSS 样式穿透(推荐)

这是最直接的方法,通过 CSS 选择器精准隐藏表头的全选复选框。

  1. 编写隐藏样式
    在你的 Vue 组件的 <style> 块中添加以下样式。如果你的样式使用了 scoped 属性,记得使用 :deep() 进行样式穿透。

    html

    <style scoped>
    /* 方法一:隐藏表头中复选框相关的元素 */
    :deep(.el-table__header-wrapper .el-checkbox) {
      display: none;
    }
    
    /* 或者方法二:更精准地隐藏选择列表头的单元格内容 */
    :deep(.el-table th.el-table__cell > .cell) {
      visibility: hidden;
    }
    
    /* 或者方法三:隐藏选择列的表头 */
    :deep(thead .el-table-column--selection .cell) {
      display: none;
    }
    </style>

    说明

    • 第一种样式直接隐藏表头区域内的复选框本身。

    • 第二种样式通过隐藏选择列表头单元格(.cell)内的所有内容来达到目的。使用 visibility: hidden; 可以保留该列表头的空间布局。

    • 你可以根据实际情况选择其中一种,通常第一种或第二种更常用。

方法二:动态设置表头单元格类名

如果你希望通过 JavaScript 逻辑来控制样式,可以使用 el-table 的 header-cell-class-name 属性。

  1. 绑定属性与方法
    在 el-table 上绑定 header-cell-class-name 属性,并指定一个方法。

    html

    <template>
      <el-table
        :data="tableData"
        ref="tableRef"
        :header-cell-class-name="headerCellClassName"
        @select="handleSelect"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <!-- 其他列 -->
      </el-table>
    </template>
  2. 定义方法添加类名
    在 <script setup> 中定义方法,为特定的表头单元格添加一个类名。

    javascript

    <script setup>
    // ... 你的其他逻辑
    
    const headerCellClassName = ({ row, column, rowIndex, columnIndex }) => {
      // 为选择列(通常是第一列)的表头单元格添加自定义类名
      if (columnIndex === 0) { // 请根据你的实际情况调整列索引
        return 'hide-header-checkbox';
      }
      return '';
    };
    </script>
  3. 为添加的类名定义样式
    在 <style> 块中为这个自定义类名添加样式。

    html

    <style scoped>
    :deep(.hide-header-checkbox .cell) {
      visibility: hidden;
    }
    </style>

💡 验证与调整

应用上述任一方法后,表格的表头全选复选框应该就被隐藏了。

如果隐藏后表头列的对齐出现偏差,你可能需要微调一下选择列或其它列的宽度,确保表头和非表头部分的宽度计算一致。

⚠️ 关于实现表格单选的额外提示

隐藏全选复选框通常是实现表格单选功能的一部分。要完善单选功能,你通常还需要配合以下逻辑:

  • 监听行选择事件:使用 @select 或 @row-click 事件来处理行点击。

  • 清除其他行的选中状态:在事件处理函数中,先使用 this.$refs.tableRef.clearSelection() 清除所有选中状态,然后使用 this.$refs.tableRef.toggleRowSelection(row, true) 选中当前行。

  • 监听选择变化:使用 @selection-change 事件来获取最终选中的行数据,并在此事件中确保选中数组 selection 的长度不超过 1。


表格单选的错误示例:

单选出现多选效果,操作实现:点击行,点击复选择,再点击其他行

错误代码:

// 点击子受理单表格的行,实现单选
const onApplyTableRowClick = (row: any, column: any) => {
  // 子受理单表格选集取消选中
  applyTableSelection.value.forEach((item) => {
    applyTable.value.toggleRowSelection(item, false);
  });
  // 选中行
  applyTable.value.toggleRowSelection(row, true);
  applyTableCurrentRow.value = row;
};

/**
 * 行复选框选中事件,当用户手动勾选某一行的 Checkbox 时触发
 * @param selection 当前选集的行数据
 * @param row 当前操作的行数据
 */
const handleSelect = (selection: Apply[], row: Apply) => {
  // // 实现方法1,实现单选,不能取消勾选,会操作出现多选效果(点击行,点击复选框,再点击其他行)
  // if (selection.length > 1) {
  //   // 如果当前选中的数量大于1,则移除之前选中的,只保留当前操作的行数据
  //   const delRow = selection.find((item) => item.applyId !== row.applyId);
  //   applyTable.value.toggleRowSelection(delRow, false); // 取消其他行的选中
  // }
  // // 选中行
  // applyTable.value.toggleRowSelection(row, true);
  // applyTableCurrentRow.value = row;

  // 实现方法2,调用表格行点击事件,实现单选,不能取消勾选,会操作出现多选效果(点击行,点击复选框,再点击其他行)
  onApplyTableRowClick(row, null);

  // // 实现方法3,实现单选,可以取消勾选
  // // 先将当前选择行数据设置为undefined,未选中状态,避免获取到上次选中的行数据
  // applyTableCurrentRow.value = undefined;
  // // 清空所有选择
  // applyTable.value.clearSelection();
  // // 如果勾选了这一行(即不是取消勾选),则重新选中当前行
  // if (selection.includes(row)) {
  //   // 选中行
  //   applyTable.value.toggleRowSelection(row, true);
  //   applyTableCurrentRow.value = row;
  // }
};



        <el-table
          ref="applyTable"
          :data="applyTableData"
          v-loading="applyTableLoading"
          highlight-current-row
          :border="true"
          style="width: 100%; height: 475px"
          :row-style="{ height: '0px', margin: '0px', padding: '0px' }"
          @row-click="onApplyTableRowClick"
          @select="handleSelect"
          @selection-change="handleApplyTableSelectionChange"
          :header-cell-class-name="handleHeaderCellClassName">

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值