app开发网站模板/武汉千锋教育培训机构怎么样
前言
在我们日常项目开发中,经常会有表格跨页多选
的需求,接下来让我们用 el-table
示例一步步来实现这个需求。
动手开发
在线体验
https://codesandbox.io/s/priceless-mcclintock-4cp7x3?file=/src/App.vue
常规版本
本部分只写了一些重点代码,心急的彦祖可以直接看 性能进阶版
- 首先我们需要初始化一个选中的数组
checkedRows
this.checkedRows = []
- 在触发选中的时候,我们就需要把当前行数据
push
到checkedRows
,否则就需要剔除对应行
<el-table ref="multipleTable" @select="handleSelectChange">
handleSelectChange (val, row) {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) {// 选中剔除this.checkedRows.splice(checkedIndex, 1)} else {// 未选中压入this.checkedRows.push(row)}
}
- 实现换页的时候的回显逻辑
this.data.forEach(row=>{const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if(checkedIndex>-1) this.$refs.multipleTable.toggleRowSelection(row,true)
})
效果预览
让我们看下此时的效果
完整代码
<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
export default {data () {return {currentPage: 1,checkedRows: [],pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}})}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},methods: {currentChange (page) {this.currentPage = pagethis.tableData.forEach(row => {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) this.$refs.multipleTable.toggleRowSelection(row, true)})},handleSelectChange (val, row) {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) {this.checkedRows.splice(checkedIndex, 1)} else {this.checkedRows.push(row)}},handleSelectAllChange (val) {this.tableData.forEach(row => {this.handleSelectChange(null, row)})}}
}
</script>
性能进阶版
性能缺陷分析
优秀的彦祖们,应该发现以上代码的性能缺陷了
1.handleSelectChange
需要执行一个 O(n)
复杂度的循环
2.currentChange
的回显逻辑内部, 有一个 O(n^2)
复杂度的循环
想象一下 如果场景中勾选的行数达到了 10000
行, 每页显示 100
条
那么我们每次点击换页 最坏情况就要执行 10000 * 100
次循环,这是件可怕的事…
重新设计数据结构
其实我们没必要把 checkedRows
设计成一个数组, 我们可以设计成一个 map
,这样读取值就只需要 O(1)
复杂度
1.改造 checkedRows
this.crossPageMap = new Map()
2.修改选中逻辑(核心代码
)
handleSelectChange (val, row) {// 实现了 O(n) 到 O(1) 的提升const checked = this.crossPageMap.has(row.id)if (checked) {this.crossPageMap.delete(row.id)} else {this.crossPageMap.set(row.id, row)}
}
3.修改换页回显逻辑
currentChange (page) {this.currentPage = page// 实现了 O(n^2) 到 O(n) 的提升this.tableData.forEach(row => {const checked = this.crossPageMap.has(row.id)if (checked) this.$refs.multipleTable.toggleRowSelection(row, true)})
}
完整代码
<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%;height:500px"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
export default {data () {return {currentPage: 1,crossPageMap: new Map(),pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}})}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},methods: {currentChange (page) {this.currentPage = pagethis.tableData.forEach(row => {const checked = this.crossPageMap.has(row.id)if (checked) this.$refs.multipleTable.toggleRowSelection(row, true)})},handleSelectChange (val, row) {const checked = this.crossPageMap.has(row.id)if (checked) {this.crossPageMap.delete(row.id)} else {this.crossPageMap.set(row.id, row)}},handleSelectAllChange (val) {this.tableData.forEach(row => {this.handleSelectChange(null, row)})}}
}
</script>
抽象业务逻辑
以上就是完整的业务代码部分,但是为了复用性。
我们考虑可以把其中的逻辑抽象成一个CrossPage
类
设计 CrossPage 类
接收以下参数
`data` - 行数据
`key` - 行数据唯一值
`max` - 最大选中行数
`toggleRowSelection` - 切换行数据选中/取消选中的方法
提供以下方法
`onRowSelectChange` - 外部点行数据点击的时候调用此方法
`onDataChange` - 外部数据变化的时候调用此方法
`clear` - 清空所有选中行
构造器大致代码 如下
constructor (options={}) {this.crossPageMap = new Map()this.key = options.key || 'id'this.data = options.data || []this.max = options.max || Number.MAX_SAFE_INTEGERthis.toggleRowSelection = options.toggleRowSelectionif(typeof this.toggleRowSelection !== 'function') throw new Error('toggleRowSelection is not function')
}
设置私有crossPageMap
彦祖们,问题来了,我们把crossPageMap
挂载到实例上,那么外部就可以直接访问修改这个变量。
这可能导致我们内部的数据逻辑错乱,所以必须禁止外部访问。
我们可以使用 #
修饰符来实现私有属性,具体参考
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Private_class_fields
完整代码
- CrossPage.js
/*** @description 跨页选择* @param {Object} options* @param {String} options.key 行数据唯一标识* @param {Array} options.data 行数据* @param {Number} options.max 最大勾选行数* @param {Function} options.toggleRowSelection 设置行数据选中/取消选中的方法,必传*/
export const CrossPage = class {#crossPageMap = new Map();constructor (options={}) {this.key = options.key || 'id'this.data = options.data || []this.max = options.max || Number.MAX_SAFE_INTEGERthis.toggleRowSelection = options.toggleRowSelectionif(typeof this.toggleRowSelection !== 'function') throw new Error('toggleRowSelection is not function')}get keys(){return Array.from(this.#crossPageMap.keys())}get values(){return Array.from(this.#crossPageMap.values())}get size(){return this.#crossPageMap.size}clear(){this.#crossPageMap.clear()this.updateViews()}onRowSelectChange (row) {if(typeof row !== 'object') return console.error('row is not object')const {key,toggleRowSelection} = thisconst checked = this.#crossPageMap.has(row[key])if(checked) this.#crossPageMap.delete(row[key])else {this.#crossPageMap.set(row[key],row)if(this.size>this.max){this.#crossPageMap.delete(row[key])toggleRowSelection(row,false)}}}onDataChange(list){this.data = listthis.updateViews()}updateViews(){const {data,toggleRowSelection,key} = thisdata.forEach(row=>{toggleRowSelection(row,this.#crossPageMap.has(row[key]))})}
}
- crossPage.vue
<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-button @click="clear">清空</el-button><el-button @click="keys">获取 keys</el-button><el-button @click="values">获取 values</el-button><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
import { CrossPage } from './CrossPage'
export default {data () {return {currentPage: 1,pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}}),multipleSelection: []}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},mounted () {this.crossPageIns = new CrossPage({key: 'id',max: 2,data: this.tableData,toggleRowSelection: this.$refs.multipleTable.toggleRowSelection})},methods: {clear () {this.crossPageIns.clear()},keys () {console.log('keys:', this.crossPageIns.keys)},values () {console.log('values:', this.crossPageIns.values)},currentChange (page) {this.currentPage = page// 调用实例 onDataChange 方法this.crossPageIns.onDataChange(this.tableData)},handleSelectChange (val, row) {// 调用实例 onRowSelectChange 方法this.crossPageIns.onRowSelectChange(row)},handleSelectAllChange (val) {this.tableData.forEach(row => {this.crossPageIns.onRowSelectChange(row)})}}
}
</script>
写在最后
未来想做的还有很多
- 利用
requestIdleCallback
提升单页大量数据的toggleRowSelection
渲染效率 - 提供默认选中项的配置
- …
相关文章:

element-ui表格跨页多选实现
前言 在我们日常项目开发中,经常会有表格跨页多选的需求,接下来让我们用 el-table 示例一步步来实现这个需求。 动手开发 在线体验 https://codesandbox.io/s/priceless-mcclintock-4cp7x3?file/src/App.vue 常规版本 本部分只写了一些重点代码,心急的彦祖可以直接看 性…...

线性代数(三) 线性方程组向量空间
前言 如何利用行列式,矩阵求解线性方程组。 线性方程组的相关概念 用矩阵方程表示 齐次线性方程组:Ax0;非齐次线性方程组:Axb. 可以理解 齐次线性方程组 是特殊的 非齐次线性方程组 如何判断线性方程组的解 其中R(A)表示矩阵A的…...

学习跨度级交互以提取方面情感三元组
方面情感三元组 方面情感三元组(Aspect Sentiment Triplet)是一种在情感分析中使用的结构,它包含三个部分:方面目标(Aspect Target)、情感(Sentiment)和对应的观点词(Op…...

那些年的Xposed开发经验记录
把之前写的Xposed相关文章合并到一块,方便查阅 目录 多进程App的Hook问题XposedHelper中的静态变量demo的AndroidManifest.xml的测试核心代码结论限制handleLoadPackage被单个进程多次执行的问题 多dex Hook问题为应用增加权限利用Xposed删除权限参考 Hook框架集锦…...

android studio内存分析之Memory profiler的使用
目录 Android Studio中内存分析工具Memory profiler的使用1. 打开Memory Profiler2. 工具使用3. 内存选项说明4. 内存性能分析器概览5. 内存计算方式6. 查看内存分配7. 捕获java/kotlin方式查看内存分配8. 堆转储文件导入和导出 内存性能分析器中的泄漏检测 Android Studio中内…...

Qt下载慢/无法下载解决方式
文章目录 一. Qt在线安装下载二. 安装方式 一. Qt在线安装下载 官网下载:https://www.qt.io/download清华源下载:https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/ 二. 安装方式 进入下载好的目录 在目录栏输入CMD&…...

【UE4 RTS】04-Camera Pan
前言 本篇实现了CameraPawn的旋转功能。 效果 步骤 1. 打开项目设置,添加两个操作映射 2. 打开玩家控制器“RTS_PlayerController_BP”,新建一个浮点型变量,命名为“PanSpeed” 在事件图表中添加如下节点 此时运行游戏可以发现当鼠标移动…...

出现raise NotImplementedError报错
在学习《动手学深度学习》时,实现下面代码时,报出raise NotImplementedError错误。 import collections import torch from d2l import torch as d2l import math from torch import nnclass Seq2SeqEncoder(d2l.Encoder):def __init__(self,vocab_size,…...

第一百二十二天学习记录:C++提高:STL-vector容器(上)(黑马教学视频)
vector基本概念 功能: vector数据结构和数组非常相似,也称为单端数组 vector与普通数组区别: 不同之处在于数组是静态空间,而vector可以动态扩展 动态扩展: 并不是在原空间之后续接新的空间,而是找更大的内…...

《Linux从练气到飞升》No.11 初识操作系统
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的…...

什么是 XSS 攻击?
概念 XSS 攻击指的是跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等。 XSS 的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了&…...

基于Spring Boot的招聘网站的设计与实现(Java+spring boot+MySQL)
获取源码或者论文请私信博主 演示视频: 基于Spring Boot的招聘网站的设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java springboot框…...

中级课程——CSRF
文章目录 案例原理挖掘 案例 原理 挖掘 挖掘详情 首先就是对目标敏感部位进行抓包分析,比如修改信息、转账、添加信息等等。通常一个数据包HTTP请求头里边都会有一个Referer,这个需要特别去验证。比如放到Burpsuit Repeater里边去测试:去掉…...

面试热题(岛屿数量)
给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均…...

【WebRTC---源码篇】(二十四)GCC获取码率后的分配
RtpTransportControllerSend::PostUpdates 配置码率 GoogCcNetworkController::GetPacingRates pacing_factor_默认2.5。也就是说pacer发送报文的码率是探测码率的2.5倍。 PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {// Pacing rate …...

数据可视化工具LightningChart .NET正式发布v10.5.1——拥有全新的3D新功能
LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科学…...

AWS认证SAA-C03每日一题
本题库由云计算狂魔微信公众号分享。 【SAA-C03助理级解决方案架构师认证】A company has a multi-tier application that runs six front-end web servers in an Amazon EC2 Auto Scaling group in a single Availability Zone behind an Application Load Balancer(ALB).A …...

ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用
Index页 右键单击“视图”文件夹,然后单击“添加”>>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新项”。 在“添加新项 - MvcMovie”对话框中: 在右上…...

基于R做宏基因组结果的PCoA分析
写在前面 因为公司给的PCA结果效果不佳,决定从中重新挑选部分样本进行再分析 步骤 表格结果预处理 在属水平genus参考原本结果已有的PCA图,尽可能挑选距离较远且聚团的样本 选取不同样本属水平的丰度数据,整理成逗号分隔的csv文件 代码…...

8.10 算法刷题【1道题】
8.10 算法刷题 22. 链表中环的入口结点(快慢指针) 22. 链表中环的入口结点(快慢指针) 原题链接 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x…...

Apache Maven:从构建到部署,一站式解决方案
目录 一、Maven介绍 1. Maven是什么? 2.Maven的作用? 二、Maven仓库介绍 2.1 库的分类 三、Maven安装与配置 3.1 Maven安装 3.2 Maven环境配置 3.3 仓库配置 四、Eclipse与Maven配置 五、Maven项目测试 5.1 新建Maven项目步骤及注意事项 5.…...

文章四:版本控制策略 - 穿越时光机:Git版本控制进阶技巧
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun 概述 版本控制是Git的核心功能,它使得开发者可以记录代码的历史变更,并能够在不同版本…...

爬虫如何应对网站的反爬机制?如何查找user-agent对应的值
import requestsurl https://movie.douban.com/top250 response requests.get(url) # 查看结果 print(response)在requests使用一文中我们有讲到,当状态码不是200时表示爬虫不可用,也就是说我们获取不到网页源代码。但是我们还是可以挣扎一下ÿ…...

一个概率论例题引发的思考
浙江大学版《概率论与梳理统计》一书中的,第13章第1节例2如下: 这个解释和模型比较简单易懂。接下来,第2节的例2是一个关于此模型的题目: 在我自己的理解中,此题的解法跟上一个题目一样,第二级传输后&…...

司徒理财:8.11黄金最新走势分析早盘1914现价多
黄金昨日再次破位新低,但是下跌力度出现衰竭迹象,意味着本次下跌暂时告一段落,行情将会开启一波反弹,早盘1914现价直接多,先看反弹上涨!黄金从走势上看,日线上已经跌至前低附近,也是…...

请写一个非对称加密工具 示例包括完整的通信流程
非对称加密工具通常用于保护数据的机密性和身份验证。下面是一个简化的示例,展示了完整的通信流程,包括密钥生成、加密、解密和数字签名验证: import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.…...

近地面无人机植被定量遥感与生理参数反演技术
遥感(RS-Remote Sensing)——不接触物体本身,用传感器收集目标物的电磁波信息,经处理、分析后,识别目标物,揭示其几何、物理性质和相互关系及其变化规律的现代科学技术。 换言之,即是“遥远的感…...

卡巴斯基为基于Linux的嵌入式设备推出专用解决方案
导读卡巴斯基在其卡巴斯基嵌入式系统安全产品中引入了对 Linux 的支持。这种适应性强的多层解决方案现在为基于Linux的嵌入式系统、设备和场景提供优化的安全,合通常适用于这些系统的严格监管标准。 卡巴斯基在其卡巴斯基嵌入式系统安全产品中引入了对 Linux 的支持…...

Word转PDF工具哪家安全?推荐好用的文件格式转换工具
Word文档是我们最常见也是最常用的办公软件,想必大家都知道了Word操作起来十分的简单,而且功能也是比较齐全的。随着科技的不断进步,如今也是有越来越多类型的办公文档,PDF就是其中之一,那么word转pdf怎么转?Word转PD…...

dma_mmap_coherent函数的使用
dma_mmap_coherent函数可以将dma地址映射到用户态,通过应用程序直接操作dma地址。 实现应该分配一段dma地址,例如: buf_addr dmam_alloc_coherent(&pdev->dev, size, &dma_addr, GFP_KERNEL);buf_addr 是内核态的虚拟地址&…...