vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作

这篇具有很好参考价值的文章主要介绍了vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

该功能存在bug哦,移步我的新博客:vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作[2]_wanghanlu_的博客-CSDN博客

在看vxe-table 文档时,发现一个功能,鼠标区域选中,觉得这个功能很好。

vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作,vue.js,前端,javascript

 但是仔细发现,这个功能不是免费的。我就想想,为啥不能自己实现呢。

下面给你看看我的最终效果:

可复制、粘贴、数值自增。

vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作,vue.js,前端,javascript

 实现步骤

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

经过上面的代码,已经可以显示我们鼠标选中的区域了。

vxe-table 鼠标滑动选择多行,鼠标区域选中批量操作,vue.js,前端,javascript

 接下来实现复制、粘贴、数值自增功能

选中的单元格的起始位置保存在selectionStart 里,结束位置保存在selectionEnd里

后续操作中根据位置获取行和列

行要用getTableData()["tableData"],

列要用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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vxe-table中树形结构

    如图,同事让帮忙实现一个需求  从二级树节点开始,同时选中的只能有一个二级树节点,选中的二级树节点之下的子节点都可以被选中。否则不能被选中 直接上代码 需要注意的是,文中树状图传递的数据是打平的数据,设置代码是下图,而不是树状图!!  上述的这一点非常

    2024年02月10日
    浏览(34)
  • 关于vxe-table全局引入的问题

    主要讲解一下vxe-table全局引入然后使用碰到的问题 0:vxe-table的官网地址 1:基本环境 (1):vue版本为3.x以上(我的是3.2.13) (2): 依赖库:xe-utils 注意:这篇博客的是vue3的脚手架搭建的,如果需要看低版本,请点击这里 2:使用npm安装 3:package.json文件里面就会有以下内

    2024年02月11日
    浏览(31)
  • vxe-table实现表格行拖拽

    1.插件文档 vex-table:https://vxetable.cn/v3/#/table/base/basic sortablejs: http://www.sortablejs.com/ 2.引入插件 vxe-table: sortablejs: 3.核心拖拽函数 渲染问题解决方法链接:sortablejs拖拽列表渲染问题 4.全代码 全代码

    2024年02月16日
    浏览(37)
  • vxe-table 表格多选框回显

    1.弹框表格结构   a-modal               v-if=\\\"visibleQuality\\\"               title=\\\"请选择需要提高的能力素质要求\\\"               :maskClosable=\\\"false\\\"               :visible=\\\"visibleQuality switchStatus\\\"               @ok=\\\"handleOkQuality\\\"               @cancel=\\\"handleCancelQuality\\\"            

    2024年02月06日
    浏览(28)
  • vue最强table vxe-table 虚拟滚动列表 前端导出

    最近遇到个问题。后台一次性返回2万条列表数据。 并且需求要求所有数据必须全部展示,不能做假分页(不能优化了)。 这些数据的直接来源就是CS客户端。 他们做CS客户端就是一次性加载几万条数据不分页(说这是客户的要求)。 我体验了一把CS客户端,数万条数据放在

    2024年02月12日
    浏览(25)
  • vue表格插件vxe-table导出 excel

    vxe-table 默认支持导出 CSV、HTML、XML、TXT格式的文件,不支持 xlsx 文件 要想导出 xlsx 文件,需要使用 vxe-table-plugin-export-xlsx 依赖  参考:https://cnpmjs.org/package/vxe-table-plugin-export-xlsx/v/2.1.0-beta 1.安装  例子: 如果用最新版的,依赖,这样使用就会报错 Uncaught (in promise) 亲测2.2.2版

    2024年01月22日
    浏览(36)
  • vxe-table表格合并单元格和编辑

    //这是在vue上面引用vxe-table插件实现的,主要方法都设置在table中,mergeCells,tableData都是在vue页面的data初使化数据, :footer-method=“footerMethod”:尾部数据,:merge-footer-items=“mergeCells”:尾部合并单元格。vxe-table网址:https://vxetable.cn/#/table/advanced/footerSpan

    2023年04月09日
    浏览(30)
  • 前端基础(Element、vxe-table组件库的使用)

    前言:在前端项目中,实际上,会用到组件库里的很多组件,本博客主要介绍Element、vxe-table这两个组件如何使用。 目录 Element 引入element 使用组件的步骤 使用对话框的示例代码 效果展示  vxe-table 引入vxe-table 成果展示 总结 官网地址 Button 按钮 | Element Plus (element-plus.org) 在m

    2024年02月10日
    浏览(27)
  • vxe-table 小众但功能齐全的vue表格组件

    一个基于 vue 的 PC 端表格组件,除了一般表格支持的增删改查、排序、筛选、对比、树形结构、数据分页等,它还支持虚拟滚动、懒加载、打印导出、虚拟列表、虚拟滚动、模态窗口、自定义模板、渲染器、贼灵活的配置项、扩展接口等,特别是能支持类似excel表格操作方式

    2024年02月08日
    浏览(34)
  • vue3 + vxe-table 封装通用Grid业务组件

    视频DEMO 功能 基于vxe-table v4 / vxe-grid 全局注册组件 无需单独引入 动态按需引入样式vite-plugin-style-import 支持传入高度 | 默认自适应高度 自定义表头 slot,实现下拉、区间、日期,并对表头参数进行校验(数字、长度、指定格式等) 自定义工具栏工具列,重写自定义列配置项,实现拖拽

    2023年04月08日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包