当前位置: 首页 > news >正文

ant-design 1.x版本表格头部拖拽、可拖拽列实现

表格列宽拖拽调整 — 问题总结版本“vue”: “2.6.11”,“vue-draggable-resizable”: “^2.3.0”,ant-design “”1.7.0“问题 1thDom为 null 导致getBoundingClientRect报错现象TypeError: Cannot read properties of null (reading getBoundingClientRect)根因onDrag中this.$set(draggingState, key, 0)触发 Vue 响应式重渲染。旧th销毁时 Vue 2 的ref回调用null清理闭包中的thDom之后dragstop事件拿到的就是null。解决用非响应式对象this._dragX作为拖拽手柄x的数据源onDrag期间不触发重渲染仅在onDragstop时通过$set提交最终值。外加if (!thDom) return防御。问题 2vue-draggable-resizabletransform 不对、拖拽错列、拖拽点乱跑现象拖拽 handle 的transform位置计算错误拖拽 A 列实际改变了 B 列的宽度。根因vue-draggable-resizable内部用transform: translateX()驱动拖拽但 CSS 把 handle 固定在right: -5pxleft: auto !important。组件内部的x定位和 CSS 定位坐标系冲突onDrag上报的x值不可信。解决移除vue-draggable-resizable依赖改用原生mousedown/mousemove/mouseup实现。Handle 仅靠 CSSright: -5px定位用鼠标位移增量delta计算新宽度彻底消除坐标系冲突。问题 3拖拽一次后位置不确定刷新 / 跳动现象拖拽过程中 handle 位置跳动释放后列宽不确定。根因同问题 1onDrag触发重渲染导致vue-draggable-resizable的xprop 被重置。解决随问题 2 一并解决原生事件方案不依赖任何响应式状态驱动拖拽位置。问题 4Scoped 样式不生效 — handlewidth: 0导致无法展示拖拽按钮现象.table-draggable-handle的width: 10px不生效handle 宽度为 0无法拖拽。其他样式如position: absolute正常。根因Vue 2 scoped 样式通过data-v-xxx属性匹配但h()在 render 函数中创建的元素不在 template 里不会自动添加 scope 属性。scoped 块line 814的width对 handle 不生效实际走的是非 scoped 块line 1040而该块之前缺少width。解决在非 scoped 样式块中补充width: 10px; top: 0; z-index: 1去掉vue-draggable-resizable时代的残留样式height: 100% !important; left: auto !important。问题 5替换 header cell 后排序失效现象拖拽列无法点击排序。根因ant-design-vue 传给components.header.cell的props是完整 VNode data 对象含class、on、style等顶层属性但代码把所有属性塞进了attrs{ attrs: { ...restProps } }导致on.click排序回调、class排序样式丢失。解决改为正确分层// 之前错误{attrs:{...restProps,width:col.width},class:resize-table-th}// 之后正确{...restProps,attrs:{...restProps.attrs,width:col.width},class:[resize-table-th,restProps.class]}问题 6拖拽结束后触发了排序现象拖拽过程中sorter图标变化释放鼠标后触发了排序请求。根因mousedown之后会触发click事件click冒泡到th被 ant-design-vue 的排序逻辑捕获。解决在拖拽 handle 上添加click: e { e.stopPropagation() }阻止click事件冒泡到th。问题 7depColumns树形结构只遍历了顶层现象depColumns是树形结构{ title: 基本情况, children: [...] }叶子节点才有dataIndex和width。但created初始化和resizeableTitle查找都只处理了顶层数组。解决两处都改为递归遍历created—walkColumns递归展开所有层级只收集叶子节点无children或children为空的列resizeableTitle—findColumn递归搜索children找到匹配的列问题 8需要按列控制可拖拽 最大/最小宽度需求只有标记了isDraggable: true的列才出现拖拽手柄支持minWidth/maxWidth限制拖拽范围解决判断条件从!col.width改为!col.isDraggableonMouseMove中用Math.min(Math.max(newWidth, col.minWidth || 50), col.maxWidth || Infinity)限制范围minWidth 默认 50px最终列配置示例{title:业务线,dataIndex:serviceLine,width:70,isDraggable:true,// 显式开启拖拽minWidth:100,// 最小宽度默认 50maxWidth:400,// 最大宽度默认无上限}最终列代码示例templatea-table bordered:columnscolumns:componentstableComponents:data-sourcedata/a-table/templatescriptimportVuefromvue;constcolumns[{title:Date,dataIndex:date,width:200,},{title:Amount,dataIndex:amount,width:100,},{title:Type,dataIndex:type,width:100,},{title:Note,dataIndex:note,width:100,},{title:Action,key:action,isDraggable:true,// 显式开启拖拽minWidth:100,// 最小宽度默认 50maxWidth:400,// 最大宽度默认无上限},];constdata[{key:0,date:2018-02-11,amount:120,type:income,note:transfer,},{key:1,date:2018-03-11,amount:243,type:income,note:transfer,},{key:2,date:2018-04-11,amount:98,type:income,note:transfer,},];exportdefault{name:App,data(){return{depColumns:data,};},computed:{tableComponents(){return{header:{cell:this.resizeableTitle,},}},},created(){constdraggingMap{}constwalkColumns(cols){cols.forEach(col{if(col.childrencol.children.length){walkColumns(col.children)}else{constkcol.dataIndex||col.keyif(col.width){draggingMap[k]col.width}}})}walkColumns(this.depColumns)this.draggingStatedraggingMap},methods:{resizeableTitle(h,props,children){letthDomnullconst{key,...restProps}propsconstfindColumn(cols,key){for(constcolofcols){if(col.childrencol.children.length){constfoundfindColumn(col.children,key)if(found)returnfound}else{constkcol.dataIndex||col.keyif(kkey)returncol}}returnnull}constcolfindColumn(this.depColumns,key)if(!col||!col.isDraggable){returnh(th,{...restProps},children)}letstartX0letstartWidth0constonMouseDowne{e.preventDefault()e.stopPropagation()startXe.pageX startWidththDom?thDom.getBoundingClientRect().width:col.widthconstonMouseMovee{constdeltae.pageX-startXconstnewWidthstartWidthdeltaconstmincol.minWidth||50constmaxcol.maxWidth||Infinitycol.widthMath.min(Math.max(newWidth,min),max)}constonMouseUp(){document.removeEventListener(mousemove,onMouseMove)document.removeEventListener(mouseup,onMouseUp)document.body.style.cursordocument.body.style.userSelectconstfinalWidththDom?thDom.getBoundingClientRect().width:col.widththis.$set(this.draggingState,key,finalWidth)col.widthfinalWidth}document.addEventListener(mousemove,onMouseMove)document.addEventListener(mouseup,onMouseUp)document.body.style.cursorcol-resizedocument.body.style.userSelectnone}consthandleElh(div,{class:table-draggable-handle,on:{mousedown:onMouseDown,click:e{e.stopPropagation()},},})returnh(th,{...restProps,attrs:{...restProps.attrs,width:col.width},class:[resize-table-th,restProps.class],ref:r{thDomr},},[...(Array.isArray(children)?children:[children]),handleEl,])},}};/scriptstyle langless.resize-table-th{position:relative;.table-draggable-handle{position:absolute;top:0;right:-5px;bottom:0;width:10px;z-index:1;cursor:col-resize;touch-action:none;}}/style
http://www.rkmt.cn/news/1296088.html

相关文章:

  • L298N电机驱动模块:从基础接线到高效稳定控制的实战指南
  • LLM知识库构建实战:从文档解析到向量检索的完整流水线
  • 手把手教你用TMS320F2802x的CMPSS模块实现逐波限流(附完整代码与避坑指南)
  • 连续XOR-SHIFT算子:统一自指递归、拓扑不变与阈值动力学的底层算子(世毫九实验室原创研究)
  • AI 写作进入长篇记忆时代,AI让小说创作更可控
  • 如何用DS4Windows让PS4手柄在PC上完美运行?3步解锁专业游戏体验
  • 从 GitHub Issue 到 PR:用 MonkeyCode 10 分钟搞定一个真实 Bug 修复
  • 番茄小说下载器:打造你的个人离线图书馆,随时随地畅享阅读自由
  • workbuddy 来解决 华南x99-4mf 设置avx2的bois信息的问题
  • 纺织行业智能化升级进入深水区:AI验布机从“可选项”变为“必选项”
  • 从零到一:手把手教你完成IDM的官网下载与系统安装
  • 从零构建IMX6ULL嵌入式系统:内核、设备树与驱动的协同编译实战
  • 陕西铝单板复合板厂家-陕西汇创建材 - 速递信息
  • 《剑与翼》:装备养成全攻略,打造强力魔幻神装
  • 昇思 Web 与 API 推理服务器部署
  • dashscope 介绍及使用(调用阿里云 AI 大模型的核心工具)
  • Oracle完全卸载教程(Windows)
  • C# Dev Tunnels使用方法 C# Visual Studio如何公开本地Web API进行调试.txt
  • 量子误差抑制技术VD在离子阱系统中的实现与优化
  • 019、神经网络基础:感知机、激活函数与多层网络
  • 如何用GenshinPlayerQuery深度分析原神账号:3个维度掌握角色成长与战斗表现
  • G-Helper:华硕笔记本终极性能控制指南 - 3分钟从新手到专家
  • 3分钟掌握C++高性能CSV解析:fast-cpp-csv-parser终极指南
  • 新手必看,五分钟完成Taotoken API Key申请与基础环境配置
  • 【Midjourney针孔相机风格终极指南】:20年AI影像专家亲授5大参数黄金配比与3种不可逆质感增强技巧
  • 你错过的立体主义黄金参数组合:仅0.3%创作者掌握的--no --weird --stylize协同策略,含3个私藏种子ID与训练逻辑溯源
  • 2026年智能电话外呼机器人机构优质推荐榜亲测效果对比
  • 基于Arduino与WiFi的物联网红外遥控器:从硬件到网页的完整实现
  • 基于树莓派与Instaloader打造自动化Instagram数字相框
  • Modelsim SE-64 2020.4调试模式实战:如何在‘Enable optimization’下像用‘-novopt’一样看全所有信号波形