Vue3 + Element Plus 实现表格全选/反选/禁用功能(示例详解)

 更新时间:2025年03月11日 14:16:10   作者:misschen888  
本文详细介绍了如何使用Vue3组合式API和ElementPlus实现表格的全选/反选/禁用功能,并分享了分页保持、视觉提示优化、性能优化等技巧,同时,还提供了常见问题的解决方案和扩展思考,帮助开发者构建功能丰富且用户体验良好的表格组件,感兴趣的朋友一起看看吧

Vue3 + Element Plus 实现表格全选/反选/禁用功能详解

一、功能概述与最终效果

本文将基于Vue3组合式API,实现Element Plus表格的以下核心功能:

  • 全选/全不选:表头复选框控制全部数据
  • 反选功能:快速反转当前选中状态
  • 行禁用:禁止选中特定数据行
  • 分页保持:分页切换时保留选中状态

二、基础表格搭建

<template>
  <div class="table-demo">
    <el-table
      ref="tableRef"
      :data="tableData"
      row-key="id"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" :selectable="checkSelectable" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="age" label="年龄" />
      <el-table-column prop="status" label="状态" />
    </el-table>
    <div class="operate-btns">
      <el-button @click="toggleAll">全选/反选</el-button>
      <el-button @click="reverseSelect">反选</el-button>
    </div>
  </div>
</template>

三、核心功能实现

1. 数据准备与禁用控制

import { ref } from 'vue'
interface TableItem {
  id: number
  name: string
  age: number
  status: '正常' | '禁用'
}
// 响应式数据
const tableRef = ref()
const tableData = ref<TableItem[]>([
  { id: 1, name: '张三', age: 25, status: '正常' },
  { id: 2, name: '李四', age: 30, status: '禁用' },
  // 更多数据...
])
// 禁用判断方法
const checkSelectable = (row: TableItem) => {
  return row.status !== '禁用'
}

2. 全选/全不选实现

const toggleAll = () => {
  // 获取当前页所有可选项
  const selectableRows = tableData.value.filter(row => checkSelectable(row))
  // 判断是否需要全选
  const shouldSelectAll = selectableRows.some(row => 
    !tableRef.value?.getRowSelected(row)
  )
  tableData.value.forEach(row => {
    if (checkSelectable(row)) {
      tableRef.value?.toggleRowSelection(row, shouldSelectAll)
    }
  })
}

3. 反选功能实现

const reverseSelect = () => {
  const currentSelection = tableRef.value?.getSelectionRows() || []
  const selectableRows = tableData.value.filter(row => checkSelectable(row))
  selectableRows.forEach(row => {
    const isSelected = currentSelection.some(
      (selected: TableItem) => selected.id === row.id
    )
    tableRef.value?.toggleRowSelection(row, !isSelected)
  })
}

4. 选中状态保持(配合分页)

// 存储选中ID
const selectedIds = ref<number[]>([])
// 监听选中变化
const handleSelectionChange = (rows: TableItem[]) => {
  selectedIds.value = rows.map(row => row.id)
}
// 分页切换时恢复选中
const handlePageChange = () => {
  nextTick(() => {
    tableData.value.forEach(row => {
      if (selectedIds.value.includes(row.id)) {
        tableRef.value?.toggleRowSelection(row, true)
      }
    })
  })
}

四、功能增强技巧

1. 表头复选框样式优化

::v-deep .el-table__header-wrapper .el-checkbox {
  display: inline-flex;
  &__inner::after {
    border-color: #fff;
  }
  &.is-disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

2. 禁用行视觉提示

<el-table :row-class-name="setDisabledStyle">
<script>
const setDisabledStyle = ({ row }: { row: TableItem }) => {
  return row.status === '禁用' ? 'disabled-row' : ''
}
</script>
<style>
.disabled-row {
  opacity: 0.6;
  cursor: not-allowed;
  td:first-child .el-checkbox {
    display: none;
  }
}
</style>

五、完整组件代码

<template>
  <div class="table-container">
    <el-table
      ref="tableRef"
      :data="tableData"
      :row-class-name="setDisabledStyle"
      row-key="id"
      @selection-change="handleSelectionChange"
    >
      <el-table-column 
        type="selection" 
        width="55" 
        :selectable="checkSelectable" 
      />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="age" label="年龄" />
      <el-table-column prop="status" label="状态" />
    </el-table>
    <div class="table-actions">
      <el-button type="primary" @click="toggleAll">
        {{ isAllSelected ? '取消全选' : '全选' }}
      </el-button>
      <el-button @click="reverseSelect">反选</el-button>
      <span class="selected-count">已选:{{ selectedIds.length }} 项</span>
    </div>
    <el-pagination 
      layout="prev, pager, next" 
      :total="50" 
      @current-change="handlePageChange"
    />
  </div>
</template>
<script setup lang="ts">
import { ref, nextTick, computed } from 'vue'
// 数据与状态定义...
// 此处插入前面章节的实现代码
</script>
<style scoped>
/* 样式优化代码... */
</style>

六、常见问题解决方案

Q1: 分页切换后选中状态丢失?

  • 方案:使用row-key绑定唯一标识,配合selection-change存储选中ID

Q2: 禁用行仍可被全选选中?

  • 检查点:
    • selectable方法是否正确返回布尔值
    • 全选逻辑是否过滤了不可选数据

Q3: 大数据量性能问题?

  • 优化建议:
    • 使用虚拟滚动(el-table-v2)
    • 避免在模板中使用复杂表达式
    • 使用Web Worker处理数据筛选

七、扩展思考

  • 服务端分页场景:需要结合接口传递选中ID集合
  • 树形表格处理:使用el-table的tree-props配置
  • 多级表头支持:嵌套el-table-column实现复杂表头
  • 无障碍访问:为操作按钮添加ARIA标签

通过合理运用Element Plus提供的API和Vue3响应式特性,可以构建出功能强大且用户体验良好的表格组件。建议在实际开发中根据具体业务需求灵活调整实现方案。

到此这篇关于Vue3 + Element Plus 实现表格全选/反选/禁用功能详解的文章就介绍到这了,更多相关Vue3 Element Plus 表格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Vue.nextTick 的实现方法

    浅谈Vue.nextTick 的实现方法

    本篇文章主要介绍了Vue.nextTick 的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Vue实现点击导航栏当前标签后变色功能

    Vue实现点击导航栏当前标签后变色功能

    这篇文章主要为大家详细介绍了Vue实现点击导航栏当前标签后变色功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • 详解Vue中的scoped及穿透方法

    详解Vue中的scoped及穿透方法

    这篇文章主要介绍了Vue中的scoped及穿透方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue项目element-ui级联选择器el-cascader回显的问题及解决

    vue项目element-ui级联选择器el-cascader回显的问题及解决

    这篇文章主要介绍了vue项目element-ui级联选择器el-cascader回显的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 详解vue.js之绑定class和style的示例代码

    详解vue.js之绑定class和style的示例代码

    本篇文章主要介绍了详解vue.js之绑定class和style的示例代码,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • vue props default Array或是Object的正确写法说明

    vue props default Array或是Object的正确写法说明

    这篇文章主要介绍了vue props default Array或是Object的正确写法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 关于vue组件的更新机制 resize() callResize()

    关于vue组件的更新机制 resize() callResize()

    这篇文章主要介绍了关于vue组件的更新机制 resize() callResize(),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue中的v-if和v-show的区别详解

    vue中的v-if和v-show的区别详解

    这篇文章主要介绍了vue中的v-if和v-show的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Vue 中获取当前时间并实时刷新的实现代码

    Vue 中获取当前时间并实时刷新的实现代码

    这篇文章主要介绍了Vue 中获取当前时间并实时刷新,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • vue router 传参获取不到的解决方式

    vue router 传参获取不到的解决方式

    今天小编就为大家分享一篇vue router 传参获取不到的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11

最新评论