文章目录
一、需求
在使用element-ui的el-table的时候,难免会遇到列太多,使用悬浮列的情况,这个是element官方封装好的,只需要添加一个fixed的属性即可实现固定列的悬浮效果。
but!!
他却没有封装更为人性化的操作,例如鼠标点击进行拖动!!
只能通过点击拖动条进行左右拖动,假如表格内容太长太多,而自己想看的数据却在第一列,显然就很不银杏化!!
emmmmm!
其实也是客户需求,简直一点都不把我们开发放在眼里,什么需求都是加加加!!
不说了解决!解决!干他就完了!
二、解决方法
1.封装一个拖动事件
创建一个js文件,将如下代码复制粘贴在js文件中。
这里是直接导出一个tablesMove 方法
代码如下(示例):
import Vue from "vue"; //这里是重中之重
export const tablesMove = function (Vue) {
// 全局添加table左右拖动效果的指令
Vue.directive("tableMove", {
bind: function (el, binding, vnode) {
var odiv = el; // 获取当前表格元素
// 修改样式小手标志
// el.style.cursor = 'pointer'
el.querySelector(".el-table .el-table__body-wrapper").style.cursor =
"pointer";
var mouseDownAndUpTimer = null;
var mouseOffset = 0;
var mouseFlag = false;
let bindRef = binding.value[0]; //绑定的表格的ref属性
odiv.onmousedown = (e) => {
const ePath = composedPath(e);
// 拖拽表头不滑动
if (
ePath.some((res) => {
return (
res &&
res.className &&
res.className.indexOf("el-table__header") > -1
);
})
)
return;
if (e.which !== 1) return;
mouseOffset = e.clientX;
mouseDownAndUpTimer = setTimeout(function () {
mouseFlag = true;
}, 80);
};
odiv.onmouseup = (e) => {
setTimeout(() => {
// 解决拖动列宽行不对齐问题--渲染表格
vnode.context.$refs[bindRef].doLayout();
}, 200);
if (mouseFlag) {
mouseFlag = false;
} else {
clearTimeout(mouseDownAndUpTimer); // 清除延迟时间
}
};
odiv.onmouseleave = (e) => {
setTimeout(() => {
// 解决拖动列宽行不对齐问题--渲染表格
vnode.context.$refs[bindRef].doLayout();
}, 200);
mouseFlag = false;
};
odiv.onmousemove = (e) => {
if (e.which !== 1) return;
const divData = odiv.querySelector(".el-table .el-table__body-wrapper");
if (mouseFlag && divData) {
// 设置水平方向的元素的位置
divData.scrollLeft -= -mouseOffset + (mouseOffset = e.clientX);
}
};
// 解决有些时候,在鼠标松开的时候,元素仍然可以拖动;
odiv.ondragstart = (e) => {
e.preventDefault();
};
odiv.ondragend = (e) => {
e.preventDefault();
};
// 是否拖拽可选中文字
odiv.onselectstart = () => {
return false;
};
//浏览器Event.path属性不存在
function composedPath(e) {
// 存在则直接return
if (e.path) {
return e.path;
}
// 不存在则遍历target节点
let target = e.target;
e.path = [];
while (target.parentNode !== null) {
e.path.push(target);
target = target.parentNode;
}
// 最后补上document和window
e.path.push(document, window);
return e.path;
}
},
});
};
2.全局引入
通过封装指令的方式,在main.js中全局引用,这样在需要使用拖动的table中添加一个指令事件即可使用,不用重复引入文件,十分方便!
代码如下(示例):
//设置表格支持拖动
import {
tablesMove } from "./util/util"; //这里是引入js文件中的方法 路径替换成自己的js路径即可
Vue.use(tablesMove);
3.在表格中使用
在el-table中定义ref以指定是哪个表格的拖动
ref="multipleTable"
将上方定义的ref名传入事件即可支持拖动事件
v-table-move="['multipleTable']"
完整代码
红框重点,ref名称一定需要一直,否则无法实现拖动效果!!