该功能存在bug哦,移步我的新博客:vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作[2]_wanghanlu_的博客-CSDN博客
在看vxe-table 文档时,发现一个功能,鼠标区域选中,觉得这个功能很好。
但是仔细发现,这个功能不是免费的。我就想想,为啥不能自己实现呢。
下面给你看看我的最终效果:
可复制、粘贴、数值自增。
实现步骤
<template>
//其他相关配置省略 这里的ref名称需要注意
<vxe-grid ref='xGrid' v-bind="gridOptions" @cell-click="tableCellClick">
</vxe-grid>
</template>
<style scoped>
.vxe-grid{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.td-mouse-active{background-color:rgb(155,204,255) !important}
</style>
JS:
<script>
export default {
data() {
return {
gridOptions:
{
size:
"small",
border: "full",
//斑马纹
stripe: true,
},
//鼠标区域选中
selectedCells: [],
// 选中的单元格数组
isSelecting: false,
// 是否正在进行选择操作
selectionStart: {
rowIndex: -1,
cellIndex: -1
},
// 选择操作起始单元格位置
selectionEnd: {
rowIndex: -1,
cellIndex: -1
},
// 选择操作结束单元格位置
}
},
mounted() {
this.init();
},
methods: {
init() {
let column = [{
width: 80,
field: "id",
title: "id"
},
{
width: 80,
field: "name",
title: "姓名"
}];
this.getTablexGrid().loadColumn(column);
this.getTablexGrid().loadData([{
id: 1,
name: "whl"
},
{
id: 2,
name: "aoliao"
}]);
this.$nextTick(() = >{
let tbody = this.getTablexGrid().$el.querySelector("table tbody");
if (tbody) {
//主要给表体添加事件
tbody.addEventListener("mousedown", this.tbodymousedown);
tbody.addEventListener("mouseup", this.tbodymouseup);
tbody.addEventListener("mousemove", this.tbodymousemove);
tbody.addEventListener("paste", this.tbodykeydown);
}
})
},
getTablexGrid() {
return this.$refs.xGrid;
},
//表格单元格点击事件
tableCellClick(e) {
if (!this.isSelecting) {
this.selectionStart = this.getCellPosition(e.$event.target);
// this.selectionStart = { rowIndex:-1, cellIndex:-1};
this.selectionEnd = this.selectionStart;
//设置样式
this.setselectedCellArea();
}
this.$emit("cell-click", e);
},
init() {
let column = [{
width: 80,
field: "id",
title: "id"
},
{
width: 80,
field: "name",
title: "姓名"
}];
this.getTablexGrid().loadColumn(column);
this.getTablexGrid().loadData([{
id: 1,
name: "whl"
},
{
id: 2,
name: "aoliao"
}]);
this.$nextTick(() = >{
let tbody = this.getTablexGrid().$el.querySelector("table tbody");
if (tbody) {
//主要给表体添加事件
tbody.addEventListener("mousedown", this.tbodymousedown);
tbody.addEventListener("mouseup", this.tbodymouseup);
tbody.addEventListener("mousemove", this.tbodymousemove);
tbody.addEventListener("paste", this.tbodykeydown);
}
})
},
tbodymousedown(event) {
//一定是左键左键
if (event.button === 0) {
// 记录选择操作起始位置
this.selectionStart = this.getCellPosition(event.target);
this.isSelecting = true;
}
},
tbodymousedown(event) {
//左键
if (event.button === 0) {
// 记录选择操作起始位置
this.selectionStart = this.getCellPosition(event.target);
this.isSelecting = true;
}
},
tbodymousemove(event) {
//左键
if (event.button === 0) {
if (!this.isSelecting) return;
// 记录选择操作结束位置
this.selectionEnd = this.getCellPosition(event.target);
//设置样式
this.setselectedCellArea();
}
},
tbodymouseup() {
//左键
if (event.button === 0) {
this.isSelecting = false;
}
},
// 获取单元格位置
getCellPosition(cell) {
while (cell.tagName !== 'TD') {
cell = cell.parentElement;
}
const rowIndex = cell.parentElement.rowIndex;
const cellIndex = cell.cellIndex;
return {
rowIndex,
cellIndex
};
},
//设置单元格选中样式
setselectedCellArea() {
let startRowIndex = this.selectionStart["rowIndex"];
let endRowIndex = this.selectionEnd["rowIndex"];
let startColumnIndex = this.selectionStart["cellIndex"];
let endColumnIndex = this.selectionEnd["cellIndex"];
let tbody = this.getTablexGrid().$el.querySelector("table tbody");
let trs = tbody.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
let tr = trs[i];
let tds = tr.getElementsByTagName("td");
for (var j = 0; j < tds.length; j++) {
let td = tds[j];
if (startRowIndex <= i && endRowIndex >= i && startColumnIndex <= j && endColumnIndex >= j) {
td.classList.add("td-mouse-active");
} else {
td.classList.remove("td-mouse-active");
}
}
}
},
}
}
</script>
经过上面的代码,已经可以显示我们鼠标选中的区域了。
接下来实现复制、粘贴、数值自增功能
选中的单元格的起始位置保存在selectionStart 里,结束位置保存在selectionEnd里
后续操作中根据位置获取行和列
行要用getTableData()["tableData"],文章来源:https://www.toymoban.com/news/detail-616829.html
列要用getTableColumn()["tableColumn"]文章来源地址https://www.toymoban.com/news/detail-616829.html
首先要给vxe-grid 添加按键事件
<vxe-grid ref='xGrid' v-bind="gridOptions" height="300px"
@cell-click="tableCellClick"
@keydown="tableKeydown">
<!-- keydown 事件 -->
</vxe-grid>
添加如下方法
//复制需要用到
import XEClipboard from 'xe-clipboard';
tableKeydown({$event}) {
let event = $event;
if (event.ctrlKey && event.keyCode === 67) {
//ctrl+c 复制
this.exec_commod("copy");
event.preventDefault();
} else if (event.ctrlKey && event.keyCode === 86) {
//ctrl+v 粘贴
this.exec_commod("paset") event.preventDefault();
} else if (event.ctrlKey && event.key === 'z') {
//ctrl+z
this.exec_commod("cellSortValue") event.preventDefault();
}
},
exec_commod(code) {
let startRowIndex = this.selectionStart["rowIndex"];
let endRowIndex = this.selectionEnd["rowIndex"];
let startColumnIndex = this.selectionStart["cellIndex"];
let endColumnIndex = this.selectionEnd["cellIndex"];
var tableData = this.getTablexGrid().getTableData()["tableData"];
var tableColumn = JSON.parse(JSON.stringify(this.getTablexGrid().getTableColumn()["tableColumn"]));
switch (code) {
//复制
case "copy":
let enterStr = "\r\n";
let spaceStr = "\t";
let data = [];
for (var i = startRowIndex; i <= endRowIndex; i++) {
let value = [];
for (var j = startColumnIndex; j <= endColumnIndex; j++) {
value.push(tableData[i][tableColumn[j].field]);
}
data.push(value);
}
let finalStr = data.map((value) = >{
return value.join(spaceStr);
}).join(enterStr);
//
if (XEClipboard.copy(finalStr)) {
this.$VXETable.modal.message({
content: '已复制到剪贴板!',
status: 'success'
});
}
break;
//粘贴
case "paset":
//由于浏览器的安全策略,只能是本地环境或者是https才能获取到剪贴板内容
navigator.clipboard.readText().then((text) = >{
if (text) {
//去除首尾换行
text = text.replace(/^\r\n+|\r\n+$/g, '');
var snsArr = text.split(/\r\n+/);
var tArr = snsArr.map((value) = >{
return value.split("\t");
}) for (var i = 0; i < tArr.length; i++) {
let line = tArr[i];
if (startRowIndex + i > tableData.length - 1) break;
let row = tableData[startRowIndex + i];
for (var j = 0; j < line.length; j++) {
if (startColumnIndex + j > tableColumn.length) break;
let column = tableColumn[startColumnIndex + j];
row[column.field] = line[j];
}
}
}
}) break;
case "cellSortValue":
var firstRow = tableData[startRowIndex];
for (var i = startRowIndex + 1; i <= endRowIndex; i++) {
if (i > tableData.length - 1) break;
for (var j = startColumnIndex; j <= endColumnIndex; j++) {
if (j > tableColumn.length - 1) break;
let value = firstRow[tableColumn[j].field];
if (!value) break;
if (!isNaN(value)) {
tableData[i][tableColumn[j].field] = parseFloat(value) + (i - startRowIndex);
} else {
//最后一个字符
let lastChar = value[value.length - 1];
//去除最后一个字符
let nvalChar = value.slice(0, -1);
if (/[a-zA-Z]/.test(lastChar)) {
let result = this.generateAlphabetChars(lastChar, i - startRowIndex + 1);
tableData[i][tableColumn[j].field] = nvalChar + result;
}
}
}
}
break;
}
},
//自增的工具方法
generateAlphabetChars(c, shift) {
/**
* 将一个字符按照指定的偏移量进行移位
* @param {string} c 需要移位的字符
* @param {number} shift 移位的偏移量
* @returns {string} 移位后的字符
*/
// 将字符转换为 ASCII 码
var asciiCode = c.charCodeAt(0);
// 计算移位后的 ASCII 码
var shiftedAsciiCode = asciiCode + shift;
let flag = false;
if (shiftedAsciiCode > 122) {
shiftedAsciiCode -= 26;
} else if (shiftedAsciiCode < 97) {
shiftedAsciiCode += 26;
}
// 将 ASCII 码转换为字符
const shiftedChar = String.fromCharCode(shiftedAsciiCode);
return asciiCode + shift > 122 ? 'a' + shiftedChar: shiftedChar;
}
到了这里,关于vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!