Element的el-table实现拖拽改变某一行的高度
刚看到这个需求的时候感觉也不难,就在官网看了一下文档,官方只支持横向拖拽改变某一列的宽度,并不支持纵向拖拽改变其高度。
于是就自己封装了一个指令
- 在项目中创建一个js文件
dragTable.js
,将一下代码复制进去,然后在使用页面引入这个js文件,然后在el-table标签中直接使用 import dragTable from './dragTable.js'
v-drag-table
import Vue from 'vue';
let resizeable = false
let mousedown = false
let newindex = null
let targetTd = null
Vue.directive('dragTable', {
inserted: function(el,binding,vnode,prevVnode) {
/* 获取头部td集合,这边是测试表格,只有一个所以直接el-table__body 的0,后续可以在<el-table> 加class,
再用querySelector
*/
let tblObj = el.getElementsByClassName("el-table__body");
//如果不用数组,最后遍历的时候不能有【】这个来选取元素
let headerRows = [];
for (const item of tblObj) {
for (const itemElement of item.rows) {
headerRows[itemElement] = itemElement.cells[0]
}
}
// 去头部的位置
let headerTds = el.getElementsByClassName("el-table__body")[0]
.rows[0];
let screenYStart = 0;
let tdHeight = 0;
for (let i = 0; i < headerRows.length; i++) {
//添加头部单元格事件
addListener(headerRows[i], "mousedown", onmousedown);
addListener(headerRows[i], "mousemove", onmousemove);
}
//鼠标点击触发事件
document.onmousedown = function(event) {
//如果不是tanle就不给他托
if(!event.target._prevClass || (event.target._prevClass && event.target._prevClass.indexOf('table') === -1)){
return
}
//获取当前行数下标
let tr = event.target.parentElement
let td = event.target.parentElement.parentElement.children
let index = 0
for (const item of td) {
item.setAttribute('id',index++)
}
newindex = tr.getAttribute('id')
if (resizeable) {
let evt = event || window.event;
mousedown = true;
screenYStart = evt.screenY;
tdHeight = targetTd.offsetHeight
}
};
//鼠标拖拽触发事件
document.onmousemove = function(event) {
//如果不是table就不给他托
if(!event.target._prevClass || (event.target._prevClass && event.target._prevClass.indexOf('table') === -1)){
return
}
let evt = event || window.event;
let srcObj = getTarget(evt);
//rowIndex是未定义!!!cellIndex是好用的。我应该获取的是tr的rowindex
//获取偏移 这里是鼠标的偏移
let offsetY = evt.offsetY;
if (mousedown) {
let newHeight = tdHeight + (evt.screenY - screenYStart) + "px"; //计算后的新的宽度,原始td+偏移
for (const item of tblObj) {
let trlist = item.getElementsByTagName('tbody')[0].children
let trIndex = parseInt(newindex)
trlist[trIndex < 0 ? 0 : trIndex].style.height = newHeight
}
} else {
//修改光标样式,ele原来头部的不能影响,于是有一些offset位置的判断,如有更好的方式请留言
srcObj.style.cursor = '';
if (
srcObj.offsetHeight - evt.offsetY <= 4 &&
srcObj.offsetWidth - evt.offsetX > 4
) {
srcObj.style.cursor = '';
targetTd = srcObj
resizeable = true;
srcObj.style.cursor = "row-resize"; //修改光标样式
} else if (evt.offsetY <= 4 && evt.offsetX > 4) {
srcObj.style.cursor = '';
if (srcObj.parentNode.rowIndex) {
resizeable = true;
// srcObj.style.cursor = "row-resize";
}
} else if (
srcObj.offsetHeight - evt.offsetY > 4 &&
srcObj.offsetWidth - evt.offsetX <= 4
) {
srcObj.style.cursor = '';
srcObj.style.cursor = "column-resize"; //修改光标样式
}
else if (evt.offsetY > 4 && evt.offsetX <= 4) {
srcObj.style.cursor = '';
if (srcObj.parentNode.rowIndex) {
// srcObj.style.cursor = "column-resize";
}
} else {
srcObj.style.cursor = '';
resizeable = false;
srcObj.style.cursor = "default";
}
}
};
//放开鼠标恢复原位
document.onmouseup = function(event) {
resizeable = false;
mousedown = false;
document.body.style.cursor = "default";
};
// 得到目标值事件
function getTarget(evt) {
return evt.target || evt.srcElement;
}
// 添加监听
function addListener(element, type, listener, useCapture) {
//这是两种写法,对应不同浏览器
element.addEventListener
? element.addEventListener(type, listener, useCapture)
: element.attachEvent("on" + type, listener);
}
},
});