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/441521

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp