场景需求:
需要支持框选,框住的行需要更改背景色来标识选中了。如下图所示
【shift+q】表示【加入】,【shift+w】表示【移除】
拆分要实现的功能:
1.框选,选中行数据
2.选中行之后,当前行的样式要有所改变
3.支持快捷键来对框选的数据进行加入/移除操作
最后实现的效果如下:
框选的功能实现基本上跟这篇文章类似,但是还是有些许的区别。
解决步骤1:在已有框选功能的基础上,调整如下
1.之前框选是指定框选必须是【编码】一列,也就是框选的区域必须包含【编码】,这样就导致表格宽度过宽时,如果想要框选交期天数为【5天】的行,还需要一一找到对应的【编码】才能进行框选。
需求更改为:不限制列名,直接进行框选。
我这边的处理方法是:给组件的行添加指定的id,给【编码】一列添加【data-id】属性,框选表格时,根据data-id的值,将行中的id放入到框选的id集合中。
1.1 编码一列的自定义插槽形式如下:
js
<template #code="{ record }">
<div class="codecls" :data-id="record.id">{{ record.code }}</div>
</template>
1.2 给表格统一遍历处理,给每一行tr添加data-id属性
js
const table = document.getElementById('containerId3');
if (table) {
const rows = table.getElementsByClassName('arco-table-tr');
Array.from(rows).forEach(row => {
// 在每一行中查找 codecls 的元素
const codeDiv = row.querySelector('.codecls');
if (codeDiv) {
const dataId = codeDiv.getAttribute('data-id');
if (dataId) {
// 将 data-id 设置到行上
row.setAttribute('data-id', dataId);
}
}
});
}
注意:在arco-design-vue
中的table
组件上,每一行的dom标签是arco-table-tr
这样下来,每一行的tr上都有对应的data-id属性了
这样就完成了【1.框选,选中行数据】
解决步骤2:实现对框选的行进行背景色的标识
js
<a-table size="mini" id="containerId3" row-key="id" :columns="columns1" :scroll="{ maxHeight: '70vh' }"
:data="selectData" :loading="loading" :pagination="false" :row-class="tableCellClass"
ref="combinedOrderTable"
></a-table>
就是上面的【row-class】可以根据某些条件对行添加对应的class类名
kuangxuanArr:就是选中的行对应的id的集合
js
tableCellClass(row) {
let cls = "item3"
if(this.kuangxuanArr.indexOf(row.id)>-1){
cls+= ' kuangxuancls';
}
return cls;
},
所以可以对kuangxuancls
添加样式:
css
.kuangxuancls .codecls,
.kuangxuancls .codecls2{
background-color:rgba(0,119,255,.2) !important;
}
【codecls】是编码一列的类名,【codecls2】是【交期天数】一列的类名,都需要改变背景色。
上面的步骤就实现了【2.选中行之后,当前行的样式要有所改变】
解决步骤3:支持快捷键来对框选的数据进行加入/移除操作
在页面加载完成后,添加如下的代码:
js
this.$nextTick(() => {
this.areaSelector3 = new AreaSelector({
element: document.getElementById('containerId3'),
selectableTargetSelector: '.item3',
datasetKeyForSelection: 'id',
onSelectChange: (arr) => {
console.log('arr11111111', arr); // arr 是一个包含被选中的元素的数组
let selectList = this.selectData.filter(item=>this.getShow(item)&&arr.indexOf(item.id)>-1)
this.kuangxuanArr = this.kuangxuanArr.concat(selectList.map(item=>item.id));
this.kuangxuanArr = [...new Set(this.kuangxuanArr)];
},
});
this.addEventListener();
});
上面的代码在文章开头的框选文章中已经是有的了,稍微做了一下修改。因为某些条件满足的情况下才能进行选中。
js
addEventListener() {
document.addEventListener('keydown', (event) => {
if ((event.key === 'Q' || event.key === 'q') && event.shiftKey) {
// shift+q 被按下
//console.log('shift+q 被按下');
if (this.kuangxuanArr.length) {
//里面的数据要加入到选中
for(let i=0;i<this.kuangxuanArr.length;i++){
let k = this.kuangxuanArr[i];
console.log(k,this.selectedKeys.indexOf(k));
if (this.selectedKeys.indexOf(k) == -1) {
let data = this.selectData.find((item) => item.id == k);
console.log('data', data);
//需要加入的数据对象就是data
}
}
this.kuangxuanArr = [];
}
}
});
document.addEventListener('keydown', (event) => {
if ((event.key === 'W' || event.key === 'w') && event.shiftKey) {
// shift+w 被按下
console.log('shift+w 被按下');
// 在这里执行你的代码
if (this.kuangxuanArr.length && this.selectedKeys.length) {
//里面的数据要从选中移除
for(let i=0;i<this.kuangxuanArr.length;i++){
let k = this.kuangxuanArr[i];
console.log(k,this.selectedKeys.indexOf(k));
if (this.selectedKeys.indexOf(k) > -1) {
let data = this.selectData.find((item) => item.id == k);
console.log('data', data);
//需要移除的数据对象就是data
}
}
this.kuangxuanArr = [];
}
}
});
},
完成!!!
最开始的框选功能中,有个地方是需要注意的:
改动如下:
将【zupdateArea】中的【this.zselectItems()】方法,改动到【zhideArea()】中。
因为之前的效果是,在框选的过程中,只要是接触到的行数据都是选中的,但是对于实际情况而言,也许框选的过程划过了1-5,实际最后的鼠标抬起只框住了1-3,此时我们想要的是1-3,而不是1-5。所以将上面的this.zselectItems()
改动到鼠标抬起的方法中就可以了。
彻底完成了!!!多多积累,多多收获!!!