目录

  • 1.先看下效果
  • 2.代码分析
    • 1.添加html代码,先将列表写出来
    • 2.初始化数据:给原数据添加index属性
    • 3.设置一个flag记录是否按下了shift键,通过监听键盘按下和松开给flag赋值
    • 4.el-checkbox勾选会触发change事件,所以在change绑定的selectionChange函数进行操作:当按住shift键时,将起止区间内的数据都选上
    • 5.由于el-checkbox-group不能拿到当前点击项,因此给el-checkbox绑定click点击事件,判断当前未按下shift键且是选中数据的操作时,将当前勾选的数据记录成起点
    • 6.全选和全不选
    • 7.反选
    • 8.优化
      • 1.防抖函数完整代码:
      • 2.引用
  • 3.完整代码

1.先看下效果


2.代码分析

1.添加html代码,先将列表写出来

<el-button @click="checkAll(true)">全选</el-button><el-button @click="checkAll(false)">全不选</el-button><el-button @click="checkInvert">反选</el-button>
<el-checkbox-group v-model="selectData" class="checkbox-group" @change="selectionChange"><el-checkboxv-for="(val, key) in tableData":key="key":label="val"@click.native="itemClick(val)">{{ val.name }}</el-checkbox>
</el-checkbox-group>

2.初始化数据:给原数据添加index属性

created() {this.tableData.forEach((item, index) => { // 遍历索引,赋值给data数据item.index = index})},

3.设置一个flag记录是否按下了shift键,通过监听键盘按下和松开给flag赋值

window.addEventListener('keydown', code => {if (code.keyCode === 16 && code.shiftKey) { // 判断是否按住shift键,是就把pin赋值为truethis.pin = true}})
window.addEventListener('keyup', code => {if(code.keyCode === 16){ // 判断是否松开shift键,是就把pin赋值为falsethis.pin = false}})

4.el-checkbox勾选会触发change事件,所以在change绑定的selectionChange函数进行操作:当按住shift键时,将起止区间内的数据都选上

// 多选框勾选触发
selectionChange(item) {const data = this.tableData // 获取所有数据const origin = this.origin // 起点数 从-1开始const endIdx = item.length === 0 ? -1 : item[item.length - 1].index // 终点数if (this.pin && item.includes(data[origin])) { // 判断按住const sum = Math.abs(origin - endIdx) + 1 // 这里记录终点const min = Math.min(origin, endIdx) // 这里记录起点let i = 0while (i < sum) {const index = min + iconst flagIdx = this.selectData.indexOf(data[index]) // 判断区间内的数据是否已选中if (flagIdx === -1) { // 值为-1表示未选中this.selectData.push(data[index])}i++}} else {// this.origin = endIdx // 没按住记录起点// console.log(endIdx);}
}

5.由于el-checkbox-group不能拿到当前点击项,因此给el-checkbox绑定click点击事件,判断当前未按下shift键且是选中数据的操作时,将当前勾选的数据记录成起点

itemClick(item) {if (!this.pin && !this.selectData.includes(item)) {this.origin = item.index // 没按住记录起点}}

6.全选和全不选

// 全选/全不选checkAll(all = true) {if (all) {this.tableData.forEach(data => {const flag = this.selectData.indexOf(data)if (flag === -1) {this.selectData.push(data)}})} else {this.selectData = []}},

7.反选

思路是将未选中的收集起来newArr,然后将已选的替换成newArr

// 反选
checkInvert: function() {const newSelectData = [] // 记录当前未选中的this.tableData.forEach(data => {const flag = this.selectData.indexOf(data)if (flag === -1) {newSelectData.push(data)}})this.selectData = newSelectData
}

8.优化

keydown在键盘按下后会不断触发,为了减少消耗,可以加上防抖函数,设置每间隔一段时间才触发事件。

1.防抖函数完整代码:
/**
* 防抖函数
* @param func 用户传入的防抖函数
* @param wait 等待的时间
* @param immediate 是否立即执行
*/
export const debounce = function(func, wait = 50, immediate = false) {// 缓存一个定时器idlet timer = nulllet resultconst debounced = function(...args) {// 如果已经设定过定时器了就清空上一次的定时器if (timer) {clearTimeout(timer)}if (immediate) {const callNow = !timer// 等待wait的时间间隔后,timer为null的时候,函数才可以继续执行timer = setTimeout(() => {timer = null}, wait)// 未执行过,执行if (callNow) result = func.apply(this, args)} else {// 开始一个定时器,延迟执行用户传入的方法timer = setTimeout(() => {// 将实际的this和参数传入用户实际调用的函数func.apply(this, args)}, wait)}return result}debounced.cancel = function() {clearTimeout(timer)timer = null}// 这里返回的函数时每次用户实际调用的防抖函数return debounced
}
2.引用
import { debounce } from '@/common/debounce' // 引入防抖函数
// 在methods中
// 监听按下键盘事件
handleKeyDown: debounce(function(code) {if (code.keyCode === 16 && code.shiftKey) { // 判断是否按住shift键,是就把pin赋值为truethis.pin = true}
}, 500, true),
handleKeyUp: debounce(function(code) {if (code.keyCode === 16) { // 判断是否松开shift键,是就把pin赋值为falsethis.pin = false}
}, 500, true)
// 在mounted中
mounted() {window.addEventListener('keydown', code => this.handleKeyDown(code)) // 监听键盘按下事件window.addEventListener('keyup', code => this.handleKeyUp(code)) // 监听键盘松开事件
},
// 在beforeDestroy中
beforeDestroy() {// 销毁监听键盘事件window.removeEventListener('keydown', code => this.handleKeyDown(code))window.removeEventListener('keyup', code => this.handleKeyUp(code))
},

3.完整代码

<template><div class="page-container"><el-button @click="checkAll(true)">全选</el-button><el-button @click="checkAll(false)">全不选</el-button><el-button @click="checkInvert">反选</el-button><el-checkbox-group v-model="selectData" class="checkbox-group" @change="selectionChange"><el-checkbox v-for="(val, key) in tableData" :key="key" :label="val" @click.native="itemClick(val)">{{ val.name }}</el-checkbox></el-checkbox-group></div>
</template><script>
import { debounce } from '@/common/debounce' // 引入防抖函数
// 参考链接 https://blog.csdn.net/weixin_43734545/article/details/103582536
export default {data() {return {origin: -1, // 这里给一个变量作为起点pin: false, // 这里给一个变量,默认为false,不按住tableData: [{date: '2016-05-01',name: '王幼虎',address: '上海市普陀区金沙江路 1511 弄'}, {date: '2016-05-02',name: '王小虎',address: '上海市普陀区金沙江路 1512 弄'}, {date: '2016-05-03',name: '王中虎',address: '上海市普陀区金沙江路 1513 弄'}, {date: '2016-05-04',name: '王老虎',address: '上海市普陀区金沙江路 1514 弄'}, {date: '2016-05-05',name: '王死虎',address: '上海市普陀区金沙江路 1515 弄'}, {date: '2016-05-06',name: '王骨虎',address: '上海市普陀区金沙江路 1516 弄'}, {date: '2016-05-07',name: '王灰虎',address: '上海市普陀区金沙江路 1517 弄'}],selectData: [] // 勾选的数据}},watch: {origin(val) {console.log(val);}},mounted() {window.addEventListener('keydown', code => this.handleKeyDown(code)) // 监听键盘按下事件window.addEventListener('keyup', code => this.handleKeyUp(code)) // 监听键盘松开事件},beforeDestroy() {// 销毁监听键盘事件window.removeEventListener('keydown', code => this.handleKeyDown(code))window.removeEventListener('keyup', code => this.handleKeyUp(code))},created() {this.tableData.forEach((item, index) => { // 遍历索引,赋值给data数据item.index = index})},methods: {// 多选框勾选触发selectionChange(item) {setTimeout(() => {const data = this.tableData // 获取所有数据const origin = this.origin // 起点数 从-1开始const endIdx = item.length === 0 ? -1 : item[item.length - 1].index // 终点数// console.log(origin);// console.log('是否批量', this.pin && item.includes(data[origin]));if (this.pin && item.includes(data[origin])) { // 判断按住const sum = Math.abs(origin - endIdx) + 1 // 这里记录终点const min = Math.min(origin, endIdx) // 这里记录起点let i = 0while (i < sum) {const index = min + iconst flagIdx = this.selectData.indexOf(data[index]) // 判断区间内的数据是否已选中if (flagIdx === -1) { // 值为-1表示未选中this.selectData.push(data[index])}i++}} else {// this.origin = endIdx // 没按住记录起点// console.log(endIdx);}}, 50);},itemClick(item) {if (!this.pin && !this.selectData.includes(item)) {this.origin = item.index // 没按住记录起点}},// 监听按下键盘事件handleKeyDown: debounce(function(code) {if (code.keyCode === 16 && code.shiftKey) { // 判断是否按住shift键,是就把pin赋值为truethis.pin = true}}, 500, true),handleKeyUp: debounce(function(code) {if (code.keyCode === 16) { // 判断是否松开shift键,是就把pin赋值为falsethis.pin = false}}, 500, true),// 全选/全不选checkAll(all = true) {if (all) {this.tableData.forEach(data => {const flag = this.selectData.indexOf(data)if (flag === -1) {this.selectData.push(data)}})} else {this.selectData = []}},// 反选checkInvert: function() {const newSelectData = [] // 记录当前未选中的this.tableData.forEach(data => {const flag = this.selectData.indexOf(data)if (flag === -1) {newSelectData.push(data)}})this.selectData = newSelectData}}
}
</script>
<style scoped lang="scss">
.page-container {width: 300px;border: 1px solid #ccc;margin: 20px auto;padding: 10px;
}
</style>
<style lang="scss">
.page-container {.checkbox-group {margin: 10px;.el-checkbox {display: block;}}
}
</style>

参考博客:原博客是以el-table为例

vue el-checkbox按下shift键实现批量选择数据相关推荐

  1. 【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件

    背景:基于Angular 6,引入ngx-ueditor 发现现象:如果以Shift键+任意键结尾,则ngModel会丢失包含shift键的字符 例如:输入"ABC+AB++++" ...

  2. 黑客攻击最短代码大揭秘!不要问,问就是5下shift键

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨Caesar 来源丨手机电脑双黑客(heike ...

  3. 0x8000 GetKeyState(VK_SHIFT); 判断是否有按下shift键

    0x8000 & GetKeyState(VK_SHIFT); 这句是判断是否有按下shift键 为什么GetAsyncKeyState()& 首先说明,有好多程序或书上是0x8000 ...

  4. Day10 -- JavaScript实现按下 Shift 键后进行多选操作的功能

    实现效果 需求分析 通过shift键实现连续多选功能 按下shift的同时点击A复选框,然后在点击B复选框,A,B之间的复选框都被勾选上 或者是先点击A复选框,再按下shift键点击B复选框,A,B之 ...

  5. 如何取消粘滞键?(连续按5下shift键会打开粘滞键)

    1.打开控制面板 2. 3. 4.

  6. 使用JUC下的CountDownLatch异步批量处理数据

    前几天有个需求让导出物流的发货信息, 比如2023年1月1日之后的 sql查了下数据量比较大, 而且需要sql查询到的数据中的一些参数, 调用外部api接口才能获取到完成的数据 由于外部api只能依次 ...

  7. Linux下redis 以关键字批量删除数据

    删除以某些key(info)开头得数据,总结了一下: 环境配置: CentOS-6,redis-3.2.8,双机主备集群 192.168.149.212:7018,7019,7020:(master) ...

  8. delphi 多个checkbox只能勾选一个_CAD加选无效?不可连续选择多个对象?按下这个键就正常了...

    CAD软件是默认可以加选的,但是有时候你可能不小心按到了哪个功能按键,导致加选功能失效,有的小伙伴就反映说自己没办法加选了,每次想要加选都需要按住Shift键才可以,大家有谁知道要怎么调回来吗? 今天 ...

  9. shift键的十一个妙用

    一.当你用QQ和别人聊天时,是不是有时信息发送的特别慢呀,不要紧,只要你发信息时按shift 键信息就会很快的发送出去的! 二.当你面对一大堆窗口,却要一个一个把它们关掉时.是不是很烦啊.只要你按sh ...

最新文章

  1. 用备份控制文件做不完全恢复下的完全恢复(数据文件备份旧--新建表空间--控制文件备份次新--日志归档文件新)...
  2. 懒加载中进行字典转模型
  3. BeanUtils的方法
  4. 下列叙述正确的是( )
  5. PHP怎么检查登录和退出,如何检查用户是否以PHP登录?
  6. 判断1个整数的二进制形式的1的个数
  7. (19)Verilog HDL顺序块:begin-end
  8. html数据摘要算法,Hash函数和消息摘要算法(示例代码)
  9. Struts2学习(二):第一个Action
  10. 算法:回溯解决电话拨号中的字母组合Letter Combinations of a Phone Number
  11. 计算机屏幕地图是不是地图,地图软件 如何在截图时超出一个屏幕?
  12. IDEA格式化代码的快捷键是什么
  13. win10 多任务 多视图 多窗口 处理快捷键
  14. HW-RTOS 概述
  15. 初创公司需不需要产品经理?
  16. OPPOA79K_OPPOA79KT_官方线刷包_救砖包_解账户锁
  17. 2、Ubuntu介绍加环境搭建详细教程
  18. win10+python开发django项目day03
  19. 手把手搭建SSM框架
  20. 利用html创建新闻页面

热门文章

  1. 小白读《锋利的jQuery(第2版)》第五章学习笔记(表单、表格)
  2. 【iphone游戏开发】Iphone游戏开发之五:游戏场景切换,点阵字的实现和Hiero工具的利用
  3. 7-1 家谱处理 超简单 40多行代码AC
  4. 匿名无人机 --- 遥控器刷中文固件
  5. 宝塔部署Yii框架多个商城项目,队列问题“服务测试失败,请检查服务是否正常运行”
  6. Noise2Noise: 实验总结——测试简记【去高斯噪声、去文本噪声】
  7. 选择大于努力-----计算机院校择校
  8. SG国家电网-ERP建设前景介绍
  9. 全国邮编前缀归属省及其备注整理,血的代价整理输出,供大家参阅
  10. oracle同义词表信息查询