el-table拖拽功能实现(3种详细解释)

本文介绍了如何在Vue的el-table中使用列宽拖拽功能以及如何实现左右table宽度拖拽,同时展示了Sortable.js库在表格列拖拽中的应用,包括setCapture和releaseCapture的使用以及CDN引入方法。
摘要由CSDN通过智能技术生成

1.el-table自带的列宽拖拽

如图:下方为el-table的属性之一,在下面代码所示的位置加上boder即可,把鼠标放在每个列之间,会出现拖拽的鼠标样式,可以调整列的宽度(但是仅限调整列宽

border是否带有纵向边框booleanfalse
  <!-- 表格 -->
    <el-table
      height="100%"
      width="100%"
      border
      resizable
      v-loading="loading"
      :data="tableData"
      @selection-change="tableSelect"
    >

2.实现左右table宽度拖拽

在使用组件的时候,尽量不要修改他,而是通过控制外面的盒子进行控制

2.1 html主要分为3部分(如图):

2.2 css样式:(样式自行设置)


    ul,li{
      list-style: none;
      display: block;
      margin:0;
      padding:0;
    }
    .lrbox{
      width:100%;
      height: 48%;
      margin: 1% 0px;
      overflow:hidden;
      display: flex;
    }
    .left{
      width:calc(50% - 20px); 
 //注意  calc() 来动态设置宽高,在表达式中运算符的前后必须要有空格
      height:100%;
    }
    .resize {
        cursor: col-resize;
        background-color: #d6d6d6;
        border-radius: 5px;
        margin-top: -10px;
        width: 10px;
        background-size: cover;
        background-position: center;
        /*z-index: 99999;*/
        font-size: 32px;
        color: white;
    }
    .resize:hover {
        color: #4444
    }  
    .mid{
      width:50%;
      height:100%;

    }

2.3 下面是js代码:

多个地方使用可以进行封装混入,提高复用率,减少代码冗余

    dragControlWidth(divWidth,resizeWidth) {  //(最小宽度int,拖动条宽度int)
     //获取
          var resize = document.getElementsByClassName('resize');
          var left = document.getElementsByClassName('left');
          var right = document.getElementsByClassName('mid');
          var box = document.getElementsByClassName('lrbox');
    //对其进行循环,可用于多个左右控制
          for (let i = 0; i < resize.length; i++) {
         //鼠标按下事件
            resize[i].onmousedown = function (e) {
              var startX = e.clientX;    //指针相对于浏览器页面(或客户区)的水平坐标
              resize[i].left = resize[i].offsetLeft;   //返回当前元素相对于 offsetParent 节点左边界的偏移像素值
         //鼠标移动事件
              document.onmousemove = function (e) {
                var endX = e.clientX;
                var moveLen = resize[i].left + (endX - startX); 
                var maxT = box[i].clientWidth - resize[i].offsetWidth; 
        //设置极值范围
                if (moveLen < divWidth) {
                  moveLen = divWidth; 
                }
                if (moveLen > maxT - divWidth){
                  moveLen = maxT  - divWidth;
                }  
       
                resize[i].style.left = moveLen; 
       //用for循环是因为相较消耗小
                for (let j = 0; j < left.length; j++) {
                  left[j].style.width = moveLen + 'px';
                  right[j].style.width = (box[i].clientWidth - moveLen - resizeWidth) + 'px';
                }
              }
          //鼠标抬起事件
              document.onmouseup = function (e) {
          //结束处理(清除事件)
                document.onmousemove = null;
                document.onmouseup = null;
                resize[i].releaseCapture && resize[i].releaseCapture();

              }
              resize[i].setCapture && resize[i].setCapture(); 
              return false;
            }
          }
   
        },

 上方提到了releaseCapturesetCapture ,下面进行简单的解释下呐,嘿嘿

2.4 releaseCapture和setCapture 介绍:

setCapture:

将鼠标事件锁定指定的元素上,当元素捕获了鼠标事件后,该事件只能作用在当前元素上。(上面代码的事件是作用中间的拖动条,拖动条的样式可以自己通过css进行美化,搞出符合自己的想法或者符合需求即可)

使用:

currElement.setCapture(boolean),用于设置是否捕获其子元素鼠标事件

注意:

1.setCapture不可作用于键盘等其它事件,只作用于鼠标事件;

2.setCapture该法是IE浏览器专有;

3.并且只能捕作用在这几个事件上

onmousedown、onmouseup、onmousemove、onclick、ondblclick、onmouseover和onmouseout

releaseCapture:

可以为指定的元素解除事件锁定,与上面的相反,一个锁定一个解锁。

(需要注意使用的是两者必须成对呈现,因为鼠标消息都发给上面锁定的这个窗口,直到调用ReleaseCapture或者调用SetCapture设置另一个窗口为止

另外,还有一个GetCapture,他是专门用来获取是哪个窗口捕获了鼠标事件

2.5 使用了releaseCapturesetCapture两次

还有重要的一点就是代码的后面使用了releaseCapturesetCapture两次

  • 这行代码的目的是检查 resize[i] 元素是否支持 releaseCapture 方法,避免在不支持该方法的浏览器中引发错误
  • 如果 resize[i] 元素支持 releaseCapture 方法,则调用一次 releaseCapture() 来释放鼠标捕获。
  • 使用两次的目的是处理特定情况下的浏览器兼容性问题。在某些浏览器中,需要多次调用 releaseCapture 才能完全释放鼠标捕获。通过使用两次调用,可以确保在各种浏览器环境下都能正确地释放鼠标捕获。

3.利用第3方插件自由拖拽

 Sortable 是一个用于可重新排序的拖放列表JavaScript 库

特征

  • 支持触摸设备和现代浏览器(包括IE9)
  • 可以从一个列表拖动到另一个列表或在同一列表中
  • 移动项目时的 CSS 动画
  • 支持拖动手柄和可选文本(比 voidberg 的 html5sortable 更好)
  • 智能自动滚动
  • 高级掉期检测
  • 流畅的动画
  • 多拖拽支持
  • 支持 CSS 转换
  • 使用原生 HTML5 拖放 API 构建

3.1效果图如下:

3.2使用 NPM 下包及引入:

也可以用pnpm,yarn下载依赖,下载慢可切换源

npm install sortablejs --save

导入到您的项目中:

import Sortable from 'sortablejs';

创建新实例
Sortable.create:HTMLElementObjectSortable  

3.3CDN:

<!-- jsDelivr :: Sortable :: Latest (https://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

 3.4代码举例:

3.4.1 使用el-table组件
<template>
	<div class="tablebox">
		<el-table :data="tableData" row-key="id" border highlight-current-row="">
			<el-table-column prop="name" label="你的大名"></el-table-column>
			<el-table-column prop="address" label="地理位置"></el-table-column>
			<el-table-column prop="date" label="那年时候"></el-table-column>
		</el-table>
	</div>
</template>
3.4.2 自定义的数据:

为了演示造的数据,正常应该是调用接口获取数据的

<script>
	import Sortable from 'sortablejs';
	export default {
		data() {
			return {
				tableData: [
					{
						id: '1',
						date: '2023-12-01',
						name: 'Juny Long',
						address: '地球村 亚洲 中国 湖南'
					},
					{
						id: '2',
						date: '2020-12-02',
						name: '琳琳1号',
						address: '地球村 亚洲 中国 贵州'
					},
					{
						id: '3',
						date: '2023-12-03',
						name: '零零七',
						address: '地球村 亚洲 中国 广东'
					},
					{
						id: '4',
						date: '2023-12-04',
						name: '龍',
						address: '地球村 亚洲 中国 香港'
					}
				],
				col: [
					{
						label: '那年时候',
						prop: 'date'
					},
					{
						label: '你的大名',
						prop: 'name'
					},
					{
						label: '地理位置',
						prop: 'address'
					}
				],
				dropCol: [
					{
						label: '那年时候',
						prop: 'date'
					},
					{
						label: '你的大名',
						prop: 'name'
					},
					{
						label: '地理位置',
						prop: 'address'
					}
				]
			}
		},

3.5 执行的方法(从而完成拖拽):

具体解释看代码就行(别跟我说看不懂)


		mounted() {
            //dom加载完成触发
			this.rowDrop();  	// 行
			this.columnDrop();   // 列
		},
		methods: {
			// 行的拖拽
			rowDrop() {
				// 获取需要拖拽的DOM对象
				const tbody = document.querySelector('.el-table__body-wrapper tbody');
                //解决指向问题
				const that = this;
                //创建新实例
				Sortable.create(tbody, {
					// 结束拖拽
					onEnd({ newIndex, oldIndex }) {
                       //   删除当前行,放到拖拽后的位置
						const currentRow = that.tableData.splice(oldIndex, 1)[0];
						that.tableData.splice(newIndex, 0, currentRow);
					}
				})
			},
			// 列的拖拽
			columnDrop() {
			// 获取需要拖拽的DOM对象
				const wrapperTr = document.querySelector('.el-table__body-wrapper tr');
				const that = this;
				Sortable.create(wrapperTr, {
                    //动画
					animation: 180,
                    //延迟
					delay: 0,
					// 结束拖拽
					onEnd: e => {
            console.log(e,'e');
           // 输出新旧的坐标(就是xy行和列的位置,不明白可以看一下输出的哦)
            console.log(e.oldIndex,e.oldDraggableIndex);
            console.log(e.newIndex,e.newDraggableIndex)

						const oldItem = that.dropCol[e.oldIndex];
						that.dropCol.splice(e.oldIndex, 1);
						that.dropCol.splice(e.newIndex, 0, oldItem);
					}
				})
			}
		}
	}
</script>
<style scoped lang="scss">
.tablebox{
  padding: 40px;
  border-radius:10px ;
background-color: #f1f1ee;
}

</style>

3.6 具体官方文档请点击下方进行跳转:

https://www.npmjs.com/package/sortablejs#cdnicon-default.png?t=N7T8https://www.npmjs.com/package/sortablejs#cdn

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

じòぴé南冸じょうげん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值