前期调研
elementUI 支持那些功能、回调?
- 宽度控制
a.宽度是否可以通过参数控制? 提供,给 el-table-column
组件添加 width
属性即可。
b.参数是首次有效,还是动态更新?动态更新所以可以使用 :width
c.是否提供了拖拽调整宽度的方案?添加border
,并且开启resizable
(默认开启)。
- 是否提供了回调函数?
header-dragend(newWidth, oldWidth, column, event)
当拖动表头改变了列的宽度的时候会触发该事件 - 是否提供了API用于获取当前宽度配置?没有提供
- 字段顺序
a.顺序是否可以通过参数控制?没提供,看了一遍并且搜索 排序、顺序、index 等关键词并无收获。主要排序能力都是对内容区域。
b.如果无法通过参数配置,那么通过什么地方可以影响到排序规则?我们可以通过修改 <el-table-column>
的顺序来控制。
分析
经过调研 elementUI 发现可以近乎完成这项工作,那么我们就不考虑其他方案了。只把获取当前宽度配置这一个问题解决就好了。
思考🤔一下,怎么改宽度?这不就 style="width: 10px"
行内样式嘛,这也太简单了。
打开控制台一看,草率😅了,干干净净什么都没有。这就离谱了,🪄魔法吗?哈哈,当然不是,我们可以看到有个 colgroup
、col
标签,专门用来控制列宽。
那就简单了,我们直接获取即可。
实现代码
宽度控制(自带)
重点是加 border
<el-table :data="tableData" border @header-dragend="headerdragend" style="width: 100%"> <el-table-column v-for="column in tableTitleList" :fixed="column.fixed" :prop="column.prop" v-if="column.isShow" :label="column.label" :width="column.width"> </el-table-column> <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button> <el-button type="text" size="small">编辑</el-button> </template> </el-table-column> </el-table>
操作之后获取宽度 @header-dragend
通过 @header-dragend
拿到通知,然后去获取节点上的真实数据
headerdragend(newWidth, oldWidth, column, e) { // 获取到触发节点,也就是你拖动的是哪一个 var el = e.target; // 获取到当前 table 的 colgroup col 节点,用于后面获取宽度 // getParentNodes 是一个模仿 $(el).parents() 的方法 var colList = getParentNodes(el, 'table').querySelectorAll('colgroup col'); // 获取当前拖动的是第几个,方便后续检测 DOM 是否已更新 var currentColIndex = this.tableTitleList.findIndex(item=>item.label == column.label); if(currentColIndex == -1){ return console.warn('找不到拖动列') } // 修改配置列表,把当前列设置为固定宽度 this.tableTitleList[currentColIndex].widthEnable = true; // 起了一个定时任务去获取最终的宽度 clearInterval(headerDragendInterval) headerDragendInterval = setInterval(()=>{ // 判断一下目标列的宽度是否为最终宽度 if(colList[currentColIndex].width == newWidth){ this.changeColumnWidth(colList); clearInterval(headerDragendInterval) }else if(colList[currentColIndex].width == oldWidth){ console.info('需要等待渲染') }else{ console.warn('异常值'); this.changeColumnWidth(colList); clearInterval(headerDragendInterval) } }, 10) }
控制顺序
因为数组是有顺序的嘛,所以使用 v-for 来循环,然后改变数组中的顺序,就可以改变渲染出来的内容顺序
<el-table :data="tableData" border @header-dragend="headerdragend" style="width: 100%"> <el-table-column v-for="column in tableTitleList" :fixed="column.fixed" :prop="column.prop" v-if="column.isShow" :label="column.label" :width="column.width"> </el-table-column> <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button> <el-button type="text" size="small">编辑</el-button> </template> </el-table-column> </el-table>
拖动排序
这块我直接使用 Sortable 来实现功能,正好也是群里一个人问的。在 onEnd 的时候把操作同步到数据源就OK了
initSort(){ var el = document.querySelector('#sortWrap') var that = this; Sortable.create(el, { delay: 100, sort: !0, forceFallback: !0, scrollSensitivity: 100, animation: 150, ghostClass: "gift-ghost-item", chosenClass: "gift-chosen-item", onEnd: function(t) { that.tableTitleList.splice( t.newIndex, 0, that.tableTitleList.splice(t.oldIndex, 1)[0] ) } }) },
下班走的匆忙,忘了测试地址:http://www.lilnong.top/static/html/vue-elementUI-table-resize-thead.html了