Ant Design table实现表头拖拽 官方 vue-draggable-resizable的魔改版

这里顺便也说一下使用官方vue-draggable-resizable组件,可能也有人不喜欢魔改版呢,我是在这里学习官方组件的使用的

官方组件的表头宽度问题大家应该要注意一下,就是全部表头的宽度不大于表格的宽度的话就会出现错乱,解决办法我就写在我的魔改版里面了。

这个魔改版是由于自己使用官方提供的 vue-draggable-resizable 出现卡顿的情况,而自己看了ElementUI的拖拽发现是真的丝滑,所以就尝试模仿一下,尝试丝滑的味道!!!

最终实现的效果如下图:

这个魔改版是用不到官方的vue-draggable-resizable组件的,就是一个div标签搞定了。

多看注释,我基本都是写在注释里面!重要:每个表头必须带dataIndex这个属性。

开始魔改:

先把主要代码放出来,在进行详细解析解析!像表头这些变量名你们看一下应该就看得懂了,我也没有大改这些名字,我就不写出来了,因为你们肯定是用过ant得表格再来的。

//这是表头从新渲染的函数
//从这里开始
(h, props, children) => {let thDom = null;let resize = falseif (!vm.visibleColumns || vm.visibleColumns[vm.visibleColumns.length-1].title == '')resize = true//这个是由于我的问题导致渲染报错,大家可以注释掉或者根据自己的情况改改const { key, ...restProps } = props;if(typeof key == 'number')returnlet colif (key === 'selection-column') {col = {};} else {col = vm.visibleColumns.find((item) => {const k = item.dataIndex || item.key;return k === key;});}if (!col || !col.width) {return <th {...restProps} >{children}</th>;}//到这里都是经过上面那篇文章学习的原代码,支持多选滴!!!//下面开始就是我自己的代码啦!let start = falselet startX = 0;let move = 0;let touch = null//鼠标移动函数const onmousemove =(e) =>{if (start){move = e.clientX-startXtouch.target.style.transform=`translateX(${move}px)`if (col.width+move < 40){//这里限制40是因为表头最小不想让它小于40onmouseup()}}}//按下函数,记录下按下的位置const moveStart =(e)=>{start = truestartX = e.clientXtouch = e//把按下的目标存好,因为移出表格之后这个事件对象会变的。touch.target.classList.add('border_right')//这个是我添加给它移动的时候的样式而已。document.addEventListener('selectstart', stopSelect);//给document添加一个不能够选中文本的事件,不然会出现边拉边选中了一堆文字内容。}let stopSelect = (e) =>{e.preventDefault();}//这是移出目标的时候依然可以拖拉的函数let moveout = (e) =>{if (start){move = e.clientX-startXtouch.target.style.transform=`translateX(${move}px)`if (col.width+move < 40){onmouseup(e)}}}//在目标外按键弹起把之前的事件清除掉let clear = (e)=>{if (start){onmouseup(e)touch = nullstart = falsedocument.removeEventListener('mousemove',moveout)}}let outEvent = () =>{if (start){document.addEventListener('mousemove',moveout)document.addEventListener('mouseup',clear)}}//这是在目标内按键弹起的函数const onmouseup = (e) =>{document.removeEventListener('selectstart', stopSelect)document.removeEventListener('mousemove',moveout)start = falsetouch.target.classList.remove('border_right')let allWidth=0;//这里需要先计算好表头的宽度,vm.visibleColumns.forEach((item, index)=>{if (item.hasOwnProperty('width') && item.dataIndex !== 'fill'){allWidth += item.width}})let movedDistance = col.width+move;let temArr = vm.visibleColumns.find(item =>{return item.title == col.title})if (movedDistance<=40){allWidth = allWidth - col.width + 40}else {allWidth = allWidth - col.width + movedDistance}let tem = document.getElementById('standard-table').getBoundingClientRect().width - 18if(vm.visibleColumns[vm.visibleColumns.length-1].dataIndex !== 'fill'){vm.visibleColumns.push({title:'',width:1,dataIndex:'fill'})}if (allWidth<tem){vm.visibleColumns[vm.visibleColumns.length-1].width = tem-allWidth-(!this.rowSelection?0:41)//41是表头多选框的宽度}else{vm.visibleColumns[vm.visibleColumns.length-1].width = 1}col.width = movedDistance <=40?40:movedDistancetouch.target.style.transform='translateX(0)'move=0touch = nullthis.$refs.actionColumns.saveVisualBlock('fa')}return (<th {...restProps} v-ant-ref={r => (thDom = r)} width={col.width} class="resize-table-th" >{children}<divclass='table-draggable-handle'onmousedown={moveStart}onmousemove={onmousemove}onmouseup={onmouseup}onmouseleave={outEvent}//这是鼠标移出目标区域的时候依然支持拖拉> </div></th>)

详细解析开始:

1、保持前面的代码

let thDom = null;let resize = falseif (!vm.visibleColumns || vm.visibleColumns[vm.visibleColumns.length-1].title == '')resize = true//这个是由于我的问题导致渲染报错,大家可以注释掉或者根据自己的情况改改const { key, ...restProps } = props;if(typeof key == 'number')returnlet colif (key === 'selection-column') {col = {};} else {col = vm.visibleColumns.find((item) => {const k = item.dataIndex || item.key;return k === key;});}if (!col || !col.width) {return <th {...restProps} >{children}</th>;}

2、修改官方组件

直接删除,改成div标签。

 return (<th {...restProps} v-ant-ref={r => (thDom = r)} width={col.width} class="resize-table-th" >{children}<divclass='table-draggable-handle'//保持样式,但是样式有一点要改。onmousedown={moveStart}onmousemove={onmousemove}onmouseup={onmouseup}onmouseleave={outEvent}//这是鼠标移出目标区域的时候依然支持拖拉> </div></th>)
看了这些代码一眼就舒服,div中有个class是使用原来的样式,但是有些要修改的,我就直接上最终的CSS代码。一共需要绑定四个事件,
  1. onmousedown
const moveStart =(e)=>{start = true//可移动标志位改变startX = e.clientX//记录开始位置的X点touch = e//把按下的目标存好,因为移出表格之后这个事件对象会变的。touch.target.classList.add('border_right')//这个是我添加给它移动的时候的样式而已。document.addEventListener('selectstart', stopSelect);//给document添加一个不能够选中文本的事件,不然会出现边拉边选中了一堆文字内容。}

点击的时候记录开始点击的位置以及修改可进入移动的状态的标志位:start
2. onmousemove

const onmousemove =(e) =>{if (start){move = e.clientX-startX//计算移动的距离touch.target.style.transform=`translateX(${move}px)`//使用transform来实现移动的效果,这样就不会出现卡顿if (col.width+move < 40){//这里限制40是因为表头最小不想让它小于40onmouseup()//小于40就直接结束移动}}}

移动的时候不修改原表头的宽度这些,使用transform来实现移动的效果
4. onmouseup

const onmouseup = (e) =>{document.removeEventListener('selectstart', stopSelect)//去除禁止选中文本事件document.removeEventListener('mousemove',moveout)//去除在目标外的移动事件start = false//改变移动的标志位,不可进行移动touch.target.classList.remove('border_right')let allWidth=0;//这里需要先计算好表头的宽度,//先计算完在把原表头宽度赋值的原因是:会出现表格错乱,//1、先计算好全部表格的宽度vm.visibleColumns.forEach((item, index)=>{if (item.hasOwnProperty('width') && item.dataIndex !== 'fill'){allWidth += item.width}})//2、计算好最终目标表头宽度let movedDistance = col.width+move;//3、把总宽度计算好if (movedDistance<=40){allWidth = allWidth - col.width + 40}else {allWidth = allWidth - col.width + movedDistance}//4、这是获取表格组件的宽度,18是边距,你们要看看你们的,不然可能会出现一点错位let tem = document.getElementById('standard-table').getBoundingClientRect().width - 18if(vm.visibleColumns[vm.visibleColumns.length-1].dataIndex !== 'fill'){//5、大坑的填补方法,使用一个空表头来填剩下来的位置,就给表头最后添加一个空表头vm.visibleColumns.push({title:'',width:1,dataIndex:'fill'})}//6、这里比较计算后总表头的宽度和表格组件的宽度比较,大于的话就把填坑大哥的宽度设为1,//否则就计算:把表格宽度减去总表头的宽度,有选择的话就需要减去那个按钮的宽度,最后赋值到填坑大哥那里去if (allWidth<tem){vm.visibleColumns[vm.visibleColumns.length-1].width = tem-allWidth-(!this.rowSelection?0:41)//41是表头多选框的宽度}else{vm.visibleColumns[vm.visibleColumns.length-1].width = 1}//7、最后就把之前的东西都清空col.width = movedDistance <=40?40:movedDistancetouch.target.style.transform='translateX(0)'move=0touch = null}

把最终位置的X点和开始的X点进行计算表头是加宽了还是变窄了,然后再改变原表头的宽度
6. onmouseleave

//离开目标对象的时候要添加移动事件和弹起事件。
let outEvent = () =>{if (start){document.addEventListener('mousemove',moveout)document.addEventListener('mouseup',clear)}
}
//在目标对象外结束的时候清空那些东西
let clear = (e)=>{if (start){onmouseup(e)touch = nullstart = falsedocument.removeEventListener('mousemove',moveout)}
}
let moveout = (e) =>{if (start){move = e.clientX-startXtouch.target.style.transform=`translateX(${move}px)`if (col.width+move < 40){onmouseup(e)}}
}

超出点击目标的时候依然可以移动,并且也给document添加mouseup事件,弹起的时候就进行上一个函数一样的计算点的位置

3、修改CSS样式

/deep/ .resize-table-th {position: relative;.table-draggable-handle {/*transform: none !important;这个要删除是因为使用transform的话就很丝滑*/position: absolute;height: 100% !important;bottom: 0;left: auto !important;right: -10px;cursor: col-resize;touch-action: none;width: 20px;}.table-draggable-handle:hover{background-image: linear-gradient(to right,#FAFAFA 40%,#36A3FF 50%,#FAFAFA 60%);opacity: 0.7;}}

这些不多讲自己看一下注释,只有一个重点。

4、修改一个比较坑的地方

刚开始说的总的表头宽度比表格的宽度小的话就会出现表格内容错乱。比如:表格的宽度是1000px,而你只有2个表头,一个100px,那总表头宽度是200px,就会有800px的空缺,如果不用一个空表头去填这个坑的话表格就会出现错乱。所以在上面的代码就会出现push一个title是空的表头信息,目前我想到的解决办法就是这个。

Ant Design table实现表头列宽拖拉 官方 vue-draggable-resizable的魔改版相关推荐

  1. React开发(230):ant design table固定表头

    固定表头 方便一页内展示大量数据.需要指定 column 的 width 属性,否则列头和内容可能不对齐. 如果指定 width 不生效或出现白色垂直空隙, 请尝试建议留一列不设宽度以适应弹性布局,或 ...

  2. Ant Design Table columns 参数配置隐藏列方法

    Ant Design Table columns 参数配置隐藏列方法 const columns = [{title: '姓名',dataIndex: 'name',key: 'name',// 隐藏 ...

  3. Ant Design Table修改滚动条样式

    Ant Design Table修改滚动条样式 目录 一.目的 二.步骤 1.了解滚动条的组成部分 2.样式修改 3.实现效果 二.总结 目录 一.目的 修改Ant表格的固定列滚动而产生的滚动条样式, ...

  4. ant design table column 设置width不生效解决方案

    ant design table column 设置width不生效解决方案 参考文章: (1)ant design table column 设置width不生效解决方案 (2)https://ww ...

  5. React开发(178):ant design table基础用法

    <Table columns={columns} dataSource={data} /> ant design重要的控制表头和数据的对象属性 columns data

  6. 关于ant design table加scroll属性后列跟表头不对齐

    class Home extends React.Component {render() {const dataSource = [{key: '1',name: '胡彦斌',age: 32,addr ...

  7. ant design table 表格空白

    据我查找,情况可能有如下几点: 1.table设置了tableLayout:fixed,导致每个格子的css的color:transparent改变了原来的颜色 2.table的columns设置了e ...

  8. ant design 动态显示隐藏表头

    主要是使用了 filterType属性, {title: "处理状态",dataIndex: "status",key: "status", ...

  9. React开发(274):ant design table额外展开行

最新文章

  1. python3.7.2怎么用不了pillow_python 3.7.0 下pillow安装方法
  2. EntityFramwork(1) 源地址https://msdn.microsoft.com/zh-cn/data/jj193542
  3. python安装redis模块_安装redis及python redis模块
  4. Spring学习笔记(三)
  5. Python time asctime()方法
  6. Git---安装步骤
  7. hashmap put复杂度_集合类HashMap,HashTable,ConcurrentHashMap区别?
  8. ORA-19809: limit exceeded for recovery files
  9. win7下用docker部署的基于openvino的yolov5算法(三)yolov5 v4.0环境安装以及.pt转成.ir模型
  10. Androd 如何使andorid应用程序的icon不在Launcher界面上显示
  11. Talk预告 | 港科大(广州)助理教授王泽宇: 提升数字内容创作中的创意实现与迭代过程
  12. 写一篇meta分析要多少时间?如何写好一篇Meta分析,你需要这样做
  13. JAVA之猜数字游戏
  14. android 模拟器 派派,派派怎么在电脑上玩?派派电脑版使用教程
  15. PyTorch载入预训练权重方法和冻结权重方法
  16. MySQL主从——GTID主从
  17. 【阿里巴巴】学习Java在面试过程中跳槽成功的心得总结
  18. Unity DOTS入门教程(Unity2019)
  19. 互联网的那点事:商业模式、开放平台、开放开源标准
  20. JAVA使用POI-TL通过Word模板生成Word文件

热门文章

  1. Java之父的高龄码农路 硅谷公司的年龄歧视
  2. 记关于SaaS平台中应对多租户模式的设计
  3. FreeType使用
  4. amesim子模型_Amesim中液压管路模型的选择方法
  5. 使用ZRender画贝塞尔曲线
  6. 我收集了一些前端在线工具
  7. 一个SAP开发人员的双截棍之路 1
  8. Linux环境下如何让可执行文件在shell中执行
  9. 楷书书法规则_1.硬笔书法楷书规则
  10. 查看B站UP开播状态(通过uid查询)