< elementUi 组件插件: el-table表格拖拽修改列宽及行高 及 使用注意事项 >

在这里插入图片描述


👉 资源Js包下载及说明

由于项目需求,需要给定原先使用的element列表新增一个列宽动态拖拽功能。结合在网上找到的资源,出一期 “ 使用事项 ” 及 使用过程中的问题汇总

> > 点击跳转资源下载 < <

👉 使用教程

由于是后期加的功能,相信大部分人都不太可能去动原先的组件。所以这个插件正好符合需求,全部代码基于原生js,不依赖任何插件,可以直接声明使用。

> 实现原理

  • 列宽的调整最终是通过调整如上图的col元素的width属性实现列宽调整的。

  • 行高的调整是动态改变tbodyel-table__row 的高度实现调整的。

注意事项:
由于是直接引用的Js文件,代码内容是针对提前预设获取dom标签,给其增加事件监听。因此,是针对当前引入页面的所有表格都有效,如需要只针对某个表格,可以在查找元素的地方传参进行判断。判断代码如下:

 const ths = document.querySelectorAll('.el-table__header th')
 const tBodyTr = document.querySelectorAll('.el-table__body tbody')
 const tbodys = document.querySelectorAll('.el-table__body-wrapper')

> 局部引入

import resizeTable from "@/utils/tabelleAnpassen";
 
// 调用方法
mounted() {
	this.$nextTick(() => {
		resizeTable();
	});
}

> 全局引入 (在main.js中)

import resizeTable from "@/utils/tabelleAnpassen";

// 挂载在vue的原型上
Vue.prototype.$resizeTable = resizeTable;
 
// 在需要使用的地方,调用方法
this.$nextTick(() => {
	this.$resizeTable();
});

以上这些使用方法,得根据实际情况来判断。判断调用方法的位置放在那个位置合适,以及有没有那种情况会导致插件失效,需要重现调用的情况。

👉 注意事项

在开发中,我们的表格往往不是一成不变的,可能会使用element表格的其他属性,或者是通过Vue指令对其造成影响。 接下来,一一讲解出现的问题及解决方案:

  • v-if 指令 包裹列表的情况下: 由于v-if会使表格出现一个重载的过程,从销毁到重现挂载。 会导致我们之前在调用这个方法的时候,获取到的dom失效,从而使插件代码无法确定表格是否存在,导致代码失效。
  • v-for 指令实现动态表头的情况下,由于 v-for 指令需要动态根据不同的数据渲染不同的表头, 也对插件获取表格具体的列数有影响,影响情况也和上面的 “ v-if ” 差不多的原因。 所以也需要在表头渲染完毕后,重现调用一下插件方法。

解决方案:v-if / v-for 的判断条件加上一个监听事件(watch),在其变化后(也就是重现挂载后),重现调用我们引入的插件方法。

  • el-table-column 上的 show-overflow-tooltip 属性,导致内容无法跟随列宽变化而变化。主要原因是因为加上该属性后,列表表格中的内容外面都嵌套了一层 .cell 的 div 且这个div的宽度跟随一开始列表预设的宽度一致,导致外面那层表格宽度变化,里面还是显示预设的宽度样式。

解决方案: 在全局中,设置样式覆盖其原先的宽度样式

.el-table .cell.el-tooltip {
  width: auto !important;
}

> 补充在搜狗浏览器中表格错位问题解决

// 关键css代码
.el-table__header colgroup col[name="gutter"] {
	display: table-cell !important;
}

具体操作,需要视具体情况而定,原因都差不多,主要是看插件能否正常获取到表格标签。

还有需要注意的是,初次调用情况的思考,比如现在vue项目用的比较多的是单页面应用项目,需要在index页面中,增加 router 路由监听器 及 mounted生命周期 的插件调用,当 路由跳转 / 刷新 时触发插件函数,就能做到全局覆盖。

> 问题补充:拖拽时导致表格滚动条消失

原因: 因为表格内容高度是由外部设置总高度 - 表头高度生成,所以当我们改变表头时,会导致表头容器被撑高,但是下方表格高度是不变的(因为样式问题,element设置了超出遮罩),所以导致滚动条被挤出可视窗口。

> 解决方案

function tableHandle(event) {
    const newPointX = getMousePos(event).x
    const moveX = newPointX - pointX
    timer = setTimeout(() => {
      thCol.forEach((el) => {
        const width = JSON.parse(JSON.stringify(currentWidth + moveX))
        if(width >= 100) {
          el.setAttribute('width', width)
        } else {
          el.setAttribute('width', 100)
        }
      })
    }, 0)
    // 在此添加使用方法
    changeHeight()
  }

// 改变表格内容容器高度
function changeHeight() {
	// 其实这里是可以直接全局搜容器标签的,但是预想到可能存在多个表格在同一页面的情况,故使用这种庸余的获取父级的方法
	const thisElBody = thCol[0].parentElement.parentElement.parentElement.parentElement.querySelector('.el-table__body-wrapper')
	if(thisElBody) {
		thisElBody.setAttribute('height', `calc(100% - ${thCol[0].offsetHeight}px)!important`)
	}
}

缺陷: 不知道什么原因,在表头缩小到某个阈值的时候,高度无法再即时获取,一直都是那个阈值。只有当再次点击的时候才能更新。

这个方法有缺陷,暂时也找不到比较合适的解决方法。暂时用用,仅以抛砖引玉,有更好的再更新上来,也希望各位大佬们能指点一二!

> 问题补充:当一个页面存在两个及两个以上表格时,无法监测拖拽多个表格表头

原因: 由于当前拖拽方法是通过查找元素的Node节点,通过监听修改对应节点的样式实现拖拽功能。但是也正因为这个原因,在搜索时,如果页面同时存在两个以上的表格,那么就会导致监听方法无法绑定在多出来的几个表格上,导致功能无法使用!

解决方法也算简单,通过给elementUI的表格组件定义不同的类名,将类名传递到拖拽方法中进行判断,实现事件绑定!不过需要注意一点的是,如果表格是动态表头的话,需要在动态渲染表头后重现调用方法,进行事件绑定!

解决方案

HTML代码(父组件)

 <el-table
	header-row-class-name="multipleTableTr"
	class="multipleTable"
>...</el-table>
 <el-table
	header-row-class-name="fileTableTr"
	class="fileTable"
>...</el-table>

<script>
// 通过传入表格的整体class名称和表头tr节点的class名称,判断不同的表格绑定
this.$nextTick(() => {
	// 此处由于小温将这个拖拽事件挂载在了vue的实例上,所以可以直接在全局调用
	this.$resizeTable('.fileTable', '.fileTableTr');
	this.$resizeTable('.multipleTable', '.multipleTableTr');
});
</script>


拖拽事件Javascript代码内

export default function resizeTable(tableName = '', thsClassName = '') {
  let thCol,
    pointX,
    currentWidth,
    pointY,
    currentHeight,
    TagEl,
    timer,
    tagTab,
    tagTabHeight,
    changeValue
 
  const ths = document.querySelectorAll((thsClassName ? (thsClassName + ' th') : '.el-table__header th'))
  const tBodyTr = document.querySelectorAll((tableName ? (tableName  + ' .el-table__body tbody') : '.el-table__body tbody'))
  const tbodys = document.querySelectorAll((tableName ? (tableName  + ' .el-table__body-wrapper') : '.el-table__body-wrapper'))

	···
}

完整的文件,将会更新在文件下载中,如有需要大伙可以去下载看看呀!


往期内容 💨

🔥 < 每日小技巧:N个很棒的 Vue 开发技巧, 持续记录ing >

🔥 < CSDN周赛解析:第 27 期 >

🔥 < 每日算法 - JavaScript解析:二叉树灯饰【初识动态规划 - dp, 具体理解配合代码看最合适,代码均有注释】 >

🔥 < JavaScript技术分享: 大文件切片上传 及 断点续传思路 >

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

技术宅小温

你小小的鼓励,是我搬砖的动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值