Element UI 实战:跨页保存表格选中状态与判断状态可选性的高效方案

本文主要是介绍Element UI 实战:跨页保存表格选中状态与判断状态可选性的高效方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

        在前文中,我们曾深入探讨了在修改数据后跨页时提醒用户可能丢失数据的问题。虽然这种方式对于一些场景是足够的,但当涉及选择框时,我们需要更为智能和高效的解决方案。在本文中,我们将分享一种基于 Element UI 的实际案例,旨在实现跨页保存选中项与禁选特定项的需求。通过以下详细讨论,你将了解到这一方案的实现原理及其用户体验效果。

问题背景

        在许多 Web 应用中,数据分页是常见的操作方式。当用户在一个页面中选择了一些数据项,然后切换到另一页时,保持之前选中的项通常是用户友好的体验。同时,可能存在一些需要禁选的执行项,例如在某些状态下,用户不应该选择或执行某些操作:如当数据可以进行执行相关操作,并且需要消耗一定时间时,我们为了任务的完整执行,会在任务执行期间,禁止选中该任务的选择框(可以预防用户进行删除等操作),后续执行完毕可以恢复初始选中状态,也可以放弃选中状态。

方案设计与实现

        在 Element UI 中,表格(Table)组件提供了丰富的特性和事件。可以利用这些特性和事件来实现跨页保存选中项和禁选执行项的需求。

实现

        1.跨页保存

        在许多 Web 应用中,数据分页是常见的操作方式。当用户在一个页面中选择了一些数据项,然后切换到另一页时,保持之前选中的项通常是用户友好的体验。

        模板
    <el-tableref="multipleTable":data="tableData"@select="handleSelectionChange"@select-all="handleSelectionAll"><el-table-column type="selection" align="center"></el-table-column><el-table-column prop="name" label="name" align="center"></el-table-column><el-table-column prop="age" label="age" align="center"></el-table-column></el-table><el-pagination:background="true":current-page.sync="queryParams.page":page-size.sync="queryParams.pageSize"layout="total,prev,pager,next,sizes":total="total":page-sizes="[5, 10, 20, 40]"@size-change="getList"@current-change="getList" />
        脚本
data() {return {total: void 0,queryParams: {page: 1,pageSize: 10,},allData: [],tableData: [],multipleSelection: [],listId: [],};},mounted() {this.getList();},methods: {getList() {this.allData = [{ name: 'A', age: 1 },{ name: 'B', age: 2 },{ name: 'C', age: 3 },{ name: 'D', age: 4 },{ name: 'E', age: 5 },{ name: 'F', age: 6 },{ name: 'G', age: 7 },{ name: 'H', age: 8 },{ name: 'I', age: 9 },{ name: 'J', age: 10 },{ name: 'K', age: 11 },{ name: 'L', age: 12 },{ name: 'M', age: 13 },{ name: 'N', age: 14 },{ name: 'O', age: 15 },{ name: 'P', age: 16 },{ name: 'Q', age: 17 },{ name: 'R', age: 18 },{ name: 'S', age: 19 },{ name: 'T', age: 20 },{ name: 'U', age: 21 },{ name: 'V', age: 22 },{ name: 'W', age: 23 },{ name: 'X', age: 24 },{ name: 'Y', age: 25 },{ name: 'Z', age: 26 },];this.total = this.allData.length;let currentPageIndex = (this.queryParams.page - 1) * this.queryParams.pageSize;let currentPageSize = this.queryParams.pageSize - 1 || 1;this.tableData = this.allData.slice(currentPageIndex, currentPageIndex + currentPageSize + 1);this.listId = [];this.tableData.forEach(item => this.listId.push(item.name));this.$nextTick(() => {this.tableData.forEach((item, index) => {if (this.multipleSelection.findIndex(v => v == item.name) >= 0) {this.$refs.multipleTable.toggleRowSelection(this.$refs.multipleTable.data[index], true);}});});},// 全选handleSelectionAll(val) {if (val.length) {const result = [];this.listId.forEach(id => {if (this.multipleSelection.every(item => item !== id)) result.push(id);});this.multipleSelection.push(...result);} else {this.listId.forEach(id => {this.multipleSelection = this.multipleSelection.filter(item => item !== id);});}},// 单选handleSelectionChange(rows, row) {if (this.multipleSelection.find(item => item === row.name)) this.multipleSelection = this.multipleSelection.filter(item => item != row.name); // 过滤(删除)else this.multipleSelection.push(row.name);},
}
        解析
  1. getList 方法:

    • 发送 HTTP GET 请求,获取数据(/.../是请求的地址,queryParams是请求参数)。
    • 在请求成功的回调中,判断返回数据的状态是否为200,如果是,将返回的数据赋值给 tableData
    • 构建 listId 数组,存储 tableData 中每一项的 id
    • 利用 $nextTick,确保在 Vue 更新 DOM 后执行,遍历 tableData,对于已经在 multipleSelection 中的项,在表格中选中对应的行。
  2. handleSelectionAll 方法:

    • 接受一个参数 val,即当前页选中的所有行数据。
    • 如果 val.length 大于 0,表示当前页有选中的行,遍历 listId,将不在 multipleSelection 中的项添加到 multipleSelection 中。
    • 如果 val.length 为 0,表示当前页没有选中的行,遍历 listId,将在 multipleSelection 中的项从中移除。
  3. handleSelectionChange 方法:

    • 接受两个参数,rows 是当前页选中的所有行数据,row 是当前操作的行数据。
    • 如果 multipleSelection 中已经存在 row.id,则将其从 multipleSelection 中移除,否则将其添加到 multipleSelection 中。

        这些方法共同实现了跨页保存选中状态的功能,通过维护 multipleSelection 数组来保存用户选择的行的 id,从而在表格分页切换时保持选中状态。

        2.禁选执行项

        数据拥有执行状态之类的字段,并且需要消耗一定时间时,我们为了任务的完整执行,会在任务执行期间,禁止选中该任务的选择框(以避免删除等操作)。执行完毕后可以恢复初始选中状态,也可以放弃选中状态。

         以下代码选择的是后者,即在重新开始运行时,禁用该项选择框并且执行完毕后不重新选中。如果希望保留,在对应执行的函数(下述为 reloadTask)中不删除 multipleSelection 中对应的id即可。

        模板
    <el-tableref="multipleTable":data="tableData"@select="handleSelectionChange"@select-all="handleSelectionAll"><el-table-column type="selection" align="center" :selectable="selectable"></el-table-column><el-table-column prop="name" label="name" align="center"></el-table-column><el-table-column prop="age" label="age" align="center"></el-table-column><el-table-column label="status"><template slot-scope="scope"><spanstyle="margin-right:10px; cursor: pointer;":class="scope.row.status !== '执行中' ? 'el-icon-caret-right' : 'el-icon-loading'"size="small":disabled="scope.row.status === '执行中'"@click="reloadTask(scope.row)"></span><el-tag :type="scope.row.status !== '执行中' ? '' : 'info'">{{scope.row.status}}</el-tag></template></el-table-column></el-table><el-pagination:background="true":current-page.sync="queryParams.page":page-size.sync="queryParams.pageSize"layout="total,prev,pager,next,sizes":total="total":page-sizes="[5, 10, 20, 40]"@size-change="getList"@current-change="getList" />
        脚本
data() {return {total: void 0,queryParams: {page: 1,pageSize: 10,},allData: [],tableData: [],multipleSelection: [],listId: [],loadingSelection: new Set(),};},mounted() {this.getList();},methods: {getList(flag = false) {if (!flag) {this.allData = [{ name: 'A', age: 1, status: '执行完毕' },{ name: 'B', age: 2, status: '执行中' },{ name: 'C', age: 3, status: '执行完毕' },{ name: 'D', age: 4, status: '未执行' },{ name: 'E', age: 5, status: '未执行' },{ name: 'F', age: 6, status: '执行中' },{ name: 'G', age: 7, status: '执行中' },{ name: 'H', age: 8, status: '执行中' },{ name: 'I', age: 9, status: '执行中' },{ name: 'J', age: 10, status: '未执行' },{ name: 'K', age: 11, status: '未执行' },{ name: 'L', age: 12, status: '未执行' },{ name: 'M', age: 13, status: '未执行' },{ name: 'N', age: 14, status: '未执行' },{ name: 'O', age: 15, status: '未执行' },{ name: 'P', age: 16, status: '未执行' },{ name: 'Q', age: 17, status: '未执行' },{ name: 'R', age: 18, status: '未执行' },{ name: 'S', age: 19, status: '未执行' },{ name: 'T', age: 20, status: '未执行' },{ name: 'U', age: 21, status: '未执行' },{ name: 'V', age: 22, status: '未执行' },{ name: 'W', age: 23, status: '未执行' },{ name: 'X', age: 24, status: '未执行' },{ name: 'Y', age: 25, status: '未执行' },{ name: 'Z', age: 26, status: '未执行' },];}this.total = this.allData.length;let currentPageIndex = (this.queryParams.page - 1) * this.queryParams.pageSize;let currentPageSize = this.queryParams.pageSize - 1 || 1;this.tableData = this.allData.slice(currentPageIndex, currentPageIndex + currentPageSize + 1);this.listId = [];this.tableData.forEach(item => this.listId.push(item.name));this.$nextTick(() => {this.tableData.forEach((item, index) => {if (this.multipleSelection.findIndex(v => v == item.name) >= 0) {this.$refs.multipleTable.toggleRowSelection(this.$refs.multipleTable.data[index], true);}});});},// 执行任务reloadTask(row) {this.multipleSelection = this.multipleSelection.filter(item => item !== row.name);row.status = '执行中';this.getList(true);},// 判断可选性selectable(row) {if (row.status !== '执行中') {if (this.loadingSelection.has(row.name)) this.loadingSelection.delete(row.name);return true;} else {this.loadingSelection.add(row.name);return false;}},// 全选handleSelectionAll(val) {if (val.length) {const result = [];this.listId.forEach(id => {if (this.multipleSelection.every(item => item !== id) && !this.loadingSelection.has(id)) result.push(id);});this.multipleSelection.push(...result);} else {this.listId.forEach(id => {this.multipleSelection = this.multipleSelection.filter(item => item !== id);});}},// 单选handleSelectionChange(rows, row) {if (this.multipleSelection.find(item => item === row.name)) this.multipleSelection = this.multipleSelection.filter(item => item != row.name); // 过滤(删除)else this.multipleSelection.push(row.name);},},
         解析

        这部分代码经过修改后主要涉及到对行的可选性(selectable 方法)以及全选处理(handleSelectionAll 方法)。下面是对修改部分代码的详细解释:

  1. selectable 方法:

    • selectable 方法用于确定给定行 row 是否可选。如果行的状态 status 不是 '执行中',则认为该行可选。
    • 如果行不可选,而且 loadingSelection 集合中已经存在该行的 id,则将其从 loadingSelection 中删除,表示加载完成。
    • 如果行可选,将其 id 添加到 loadingSelection 集合中,表示正在加载中,并返回 false 表示不可选;否则,返回 true 表示可选。
  2. handleSelectionAll 方法:

    • 该方法用于处理全选操作。接收参数 val,即当前页选中的所有行数据。
    • 如果有选中的行,遍历 listId,将不在 multipleSelection 中且不在 loadingSelection 中的项添加到 multipleSelection 中。
    • 如果没有选中的行,遍历 listId,将在 multipleSelection 中的项从中移除。

        这些修改主要增加了对行的可选性的判断,以及对加载状态的管理,通过 loadingSelection 集合来标记哪些行正在加载中。这样可以更好地控制在某些条件下禁止选择或在加载中时保持选择状态。

实现效果

跨页保存

禁选某些状态

这篇关于Element UI 实战:跨页保存表格选中状态与判断状态可选性的高效方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/441472

相关文章

Python与DeepSeek的深度融合实战

《Python与DeepSeek的深度融合实战》Python作为最受欢迎的编程语言之一,以其简洁易读的语法、丰富的库和广泛的应用场景,成为了无数开发者的首选,而DeepSeek,作为人工智能领域的新星... 目录一、python与DeepSeek的结合优势二、模型训练1. 数据准备2. 模型架构与参数设置3

Java实战之利用POI生成Excel图表

《Java实战之利用POI生成Excel图表》ApachePOI是Java生态中处理Office文档的核心工具,这篇文章主要为大家详细介绍了如何在Excel中创建折线图,柱状图,饼图等常见图表,需要的... 目录一、环境配置与依赖管理二、数据源准备与工作表构建三、图表生成核心步骤1. 折线图(Line Ch

Java使用Tesseract-OCR实战教程

《Java使用Tesseract-OCR实战教程》本文介绍了如何在Java中使用Tesseract-OCR进行文本提取,包括Tesseract-OCR的安装、中文训练库的配置、依赖库的引入以及具体的代... 目录Java使用Tesseract-OCRTesseract-OCR安装配置中文训练库引入依赖代码实

MySQL 中的服务器配置和状态详解(MySQL Server Configuration and Status)

《MySQL中的服务器配置和状态详解(MySQLServerConfigurationandStatus)》MySQL服务器配置和状态设置包括服务器选项、系统变量和状态变量三个方面,可以通过... 目录mysql 之服务器配置和状态1 MySQL 架构和性能优化1.1 服务器配置和状态1.1.1 服务器选项

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解