table
表格使用的是ant-design-vue
组件库中的表格,但是所有表格同理
想要去实现拉伸表格滚动区域高度的功能(鼠标选中表格底部边框来拉伸整个表格滚动区域高度)
实现想法:
- 开始:为
table
设置::after
伪元素向table
表格的底部添加一个边框,再对该伪类设置事件,但是问题是伪类不是真实dom
所以无法获取到该伪类 - 结果:使用
js
添加新元素模拟伪类的效果,为table
表格的底部添加一个边框,再为该边框设置拖动事件,就可以去修改表格的高度
实现过程:
- 首先要先获取到
table
表格的dom元素
,两种方法:- 在表格本身设置
ref
属性来获取到该表格,获取到之后在$refs.xxxx
基础上.$el
来获取到表格的dom元素
- 直接在浏览器打开控制台找到组件库封装表格的类,在
antd
组件库中:表格的类名为.ant-table
,所以直接使用WebAPI
的方法document.querySelector('.ant-table')
来获取到该表格的dom元素
(我使用的方法,防止表格过多需要依次对表格赋值相同的ref
属性,目的是可以封装逻辑,即可批量对表格实现高度拉伸)
- 在表格本身设置
- 获取到了表格的
dom元素
之后,接下来使用js
在该表格的底部添加一个新元素 ,该元素模拟table
表格的底部边框,实现视觉上拉伸表格的底部边框来实现整个table
表格高度的伸缩,对用户操作更友好 - 添加了
table
表格底部边框的元素之后,对新添加的元素设置mousedown
事件,当鼠标按下触发修改表格高度的方法,实现功能。
实现代码:
1. 第一步: 在mounted
生命周期钩子函数等待dom
渲染完毕后,获取table
表格在该表格底部添加一个新元素模拟表格的底部边框(拖动条)
javascript
methods: {
// table纵向拖拽: 设置一个表格底部的拖拽条,注册事件
setTableRowScroll() {
this.$nextTick(() => {
// 获取 .ant-table 表格元素
const antTable = document.querySelector('.ant-table');
// 创建伪元素的替代元素
const afterElement = document.createElement('div');
afterElement.style.position = 'absolute';
afterElement.style.bottom = '-4px';
afterElement.style.cursor = 'row-resize';
afterElement.style.height = '5px';
afterElement.style.width = '100%';
afterElement.style.backgroundColor = '#e8e8e8';
// 将创建的元素添加到 .ant-table 元素中
antTable.appendChild(afterElement);
// 添加事件监听器
afterElement.addEventListener('mousedown', this.startResizing);
})
},
}
mounted() {
this.setTableRowScroll()
}
设置完成拖动条之后,在表格的底部可以显示该拖动条,此时当鼠标按住就可以触发mousedown
事件(startResizing方法
)
2. 第二步: 触发拖动条拖拽(mousedown
)的方法=>startResizing()
javascript
data() {
return {
isResizing: false // 判断对 document 设置鼠标移动则触发事件,反之则不触发事件
}
}
methods: {
startResizing() {
this.isResizing = true
document.addEventListener('mousemove', this.handleMouseMove);
document.addEventListener('mouseup', this.handleMouseUp);
}
}
此时当鼠标按下拖动条之后,触发的方法中对document
设置了mousemove
事件,目的是:当鼠标按下滚动条之后想要进行滚动条以及所属的table
表格高度伸缩的效果,为document
设置鼠标移动事件,是为了当按下拖动条之后,鼠标不在拖动条的位置也可以触发该事件
更详细地解释:
- 当按下鼠标左键时,触发
mousedown
事件。在这个事件中,开始监听mousemove
和mouseup
事件,以便追踪鼠标移动和释放的动作。 - 如果只在拖拽条上添加
mousemove
和mouseup
事件监听器,那么当鼠标移动到拖拽条之外的区域时,这两个事件将不再被捕获,拖拽功能将不再响应。 - 通过将
mousemove
和mouseup
事件监听器添加到document
上,可以确保在鼠标移动到页面的任何地方时都能够捕获这两个事件。这是因为document
代表整个页面,鼠标移动或释放时,事件将被传递到document
。
综上所述,将事件监听器添加到 document
是一种确保在全局范围内捕获鼠标移动和释放事件的常见做法,以确保拖拽功能能够在整个页面中正确运作。
3. 第三步: 设置真正的拖拽表格的方法handleMouseMove
,以及鼠标释放的方法handleMouseUp
javascript
methods: {
// 拖动事件
handleMouseMove(e) {
if (this.isResizing) {
const mouseY = e.pageY;
this.windowHeight = mouseY - 320
// document.querySelector('div.ant-table-body').style.maxHeight = `${mouseY}px`
}
},
// 取消拖动事件
handleMouseUp() {
this.isResizing = false;
document.removeEventListener('mousemove', this.handleMouseMove);
document.removeEventListener('mouseup', this.handleMouseUp);
},
}
由于我在table
表格上设置的可滚动高度为windowHeight
,所以在此我对windowHeight
进行鼠标移动Y轴高度的赋值。
此时就实现了拖动表格底部边框来实现表格高度伸缩的功能!
完整代码:
这里我使用的mixin
l对拉伸表格高度的逻辑进行封装,以便可以对多个页面进行复用,vue3
组合式可以使用组合式函数完成逻辑封装
javascript
/**
* table表格纵向拖拽的公共组件,mixin.js
*/
export const tableRowResize = {
data() {
return {
windowHeight: document.documentElement.clientHeight - 400,
isResizing: false,
}
},
methods: {
startResizing() {
this.isResizing = true;
document.addEventListener('mousemove', this.handleMouseMove);
document.addEventListener('mouseup', this.handleMouseUp);
},
// 拖动事件
handleMouseMove(e) {
if (this.isResizing) {
const mouseY = e.pageY;
this.windowHeight = mouseY - 320
// document.querySelector('div.ant-table-body').style.maxHeight = `${mouseY}px`
}
},
// 取消拖动事件
handleMouseUp() {
this.isResizing = false;
document.removeEventListener('mousemove', this.handleMouseMove);
document.removeEventListener('mouseup', this.handleMouseUp);
},
// table纵向拖拽: 设置一个表格底部的拖拽条,注册事件
setTableRowScroll() {
this.$nextTick(() => {
// 获取 .ant-table 表格元素
const antTable = document.querySelector('.ant-table');
// 创建伪元素的替代元素
const afterElement = document.createElement('div');
afterElement.style.position = 'absolute';
afterElement.style.bottom = '-4px';
afterElement.style.cursor = 'row-resize';
afterElement.style.height = '5px';
afterElement.style.width = '100%';
afterElement.style.backgroundColor = '#e8e8e8';
// 将创建的元素添加到 .ant-table 元素中
antTable.appendChild(afterElement);
// 添加事件监听器
afterElement.addEventListener('mousedown', this.startResizing);
})
},
},
mounted() {
this.setTableRowScroll()
}
}
附加一个table
的模板:
javascript
<template>
<a-table :columns="columns" :data-source="dataSource" :scroll="{ x: 1000, y: windowHeight }" />
</template>
<script>
import { tableRowResize } from './mixin.js'
export default {
mixins: [tableRowResize]
}
</script>