基于elementUI table组件实现自定义列,宽度,排序并联动同步

简介: 哈喽,大家好又是我。昨天有个人在群里问:“基于 elementUI 如何实现拖动修改列宽度,并同步在多个表格中”。这个功能其实听常见的,在不同的使用者眼中关注点就应该是不一样的。比如:项目的主管,更关心进度前端开发,关心设计稿、接口什么时候提供后端开发,关心前端什么时候写完,什么时候联调测试人员,关心什么时候提测,以及对应人员是谁我们的目的是:针对于不同的人群,显示不同的字段,不同的排序规则(index、fixed)。那好,我们先来分析一下实现这样的功能都需要做什么。

前期调研


elementUI 支持那些功能、回调?


  1. 宽度控制


a.宽度是否可以通过参数控制? 提供,给 el-table-column 组件添加 width 属性即可。


b.参数是首次有效,还是动态更新?动态更新所以可以使用 :width


c.是否提供了拖拽调整宽度的方案?添加border,并且开启resizable(默认开启)。


  1. 是否提供了回调函数?header-dragend(newWidth, oldWidth, column, event) 当拖动表头改变了列的宽度的时候会触发该事件
  2. 是否提供了API用于获取当前宽度配置?没有提供


  1. 字段顺序


a.顺序是否可以通过参数控制?没提供,看了一遍并且搜索 排序、顺序、index 等关键词并无收获。主要排序能力都是对内容区域。


b.如果无法通过参数配置,那么通过什么地方可以影响到排序规则?我们可以通过修改 <el-table-column> 的顺序来控制。


分析


经过调研 elementUI 发现可以近乎完成这项工作,那么我们就不考虑其他方案了。只把获取当前宽度配置这一个问题解决就好了。


思考🤔一下,怎么改宽度?这不就 style="width: 10px" 行内样式嘛,这也太简单了。


bVcTLYD.webp.jpg


打开控制台一看,草率😅了,干干净净什么都没有。这就离谱了,🪄魔法吗?哈哈,当然不是,我们可以看到有个 colgroupcol 标签,专门用来控制列宽。


bVcTLZH.webp.jpg


那就简单了,我们直接获取即可。


实现代码



宽度控制(自带)


重点是加 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

相关文章
|
开发框架 前端开发 JavaScript
在Vue&Element前端项目中,使用FastReport + pdf.js生成并展示自定义报表
在Vue&Element前端项目中,使用FastReport + pdf.js生成并展示自定义报表
有关element UI el-table 跟el-dialog搭配使用出现的问题,背景问题,穿透问题
有关element UI el-table 跟el-dialog搭配使用出现的问题,背景问题,穿透问题
676 0
|
前端开发 JavaScript API
在 Vue3 + Element Plus 中生成动态表格,动态修改表格,多级表头,合并单元格
在 Vue 中,表格组件是使用频率及复杂度排名第一的组件,前端经常需要根据后台返回的数据动态渲染表格,比如动态表格如何生成,因为表格的列并不是固定的,在未知表格具体有哪些列的场景下,前端如何动态渲染表格数据。又或者需要把表格单元格进行合并处理,比如第一列是日期,需要把相同的日期进行合并,这样表格看起来会更加清晰。 本文手把手教你如何在 Vue3 + Element Plus 中创建表格、生成动态表格、创建动态多级表头、表格行合并、列合并等问题。如果你正在搭建后台管理工具,又不想处理前端问题,推荐使用卡拉云 ,卡拉云是新一代低代码开发工具,可一键接入常见数据库及 API ,无需懂前端,仅需拖拽即
3456 0
|
数据格式
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
本文介绍了在ElementUI和ElementPlus中使用`el-table`组件实现合并行功能的技巧,包括多列合并和单列合并的方法,并提供了相应的示例代码和运行效果。
9169 1
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
|
存储 JavaScript 容器
Element UI表格拖拽(vue中) —— 行拖拽、列拖拽
Element UI表格拖拽(vue中) —— 行拖拽、列拖拽
2185 0
|
数据格式
ECharts 饼图
本章节我们将绘制饼图。
366 15
Vue3步骤条(Steps)
这是一个基于 Vue2 的步骤条(Steps)组件,支持多种自定义属性,如步骤数组、宽度、大小、垂直显示、标签位置等。通过 `v-model` 可实现步骤的动态切换和点击交互。提供了丰富的样式调整选项,适用于各种场景下的多步骤流程引导。组件内详细展示了如何创建和使用步骤条,并提供了多个示例代码片段。
1491 4
Vue3步骤条(Steps)
elementui表格自定义表头的两种方法
这篇文章主要是总结了elementui-table表格怎么自定义表头,两种方式需求不一样,大家还有啥好的方法或者遇到的bug评论区留言大家一起解决。
1893 0
|
编解码 JavaScript
【vue2】vue2 适配pc端,解决浏览器缩放问题,解决电脑显示设置缩放、分辨率问题
【vue2】vue2 适配pc端,解决浏览器缩放问题,解决电脑显示设置缩放、分辨率问题
1626 1
|
前端开发 JavaScript
js 等待接口访问成功后执行指定代码【3种方法】(含async await Promise的使用)
js 等待接口访问成功后执行指定代码【3种方法】(含async await Promise的使用)
634 1