Element-UI Table组件上添加列拖拽效果实现方法

2020-06-14 06:00:24易采站长站整理

Element-UI 的 Table 组件很强大,但是我们的需求更强大…

简单粗暴的来一发效果图:

一、数据驱动

传统的拖动效果,都是基于通过 mousedown、mousemove、mouseup 事件来修改删减 dom 节点

但 Vue 是一个数据驱动的前端框架,开发时应尽量避免操作 dom

而且 Element-UI 的 Table 组件封装得很严谨,直接操作 dom 很容易产生不可预计的 bug

所以我的核心思路就是:通过一个数组渲染表头(列),然后修改这个数组的顺序,从而修改列表的列排序

template 部分:


<div class="w-table" :class="{'w-table_moving': dragState.dragging}">
<el-table :data="data"
:border="option.border"
:height="option.height"
:max-height="option.maxHeight"
:style="{ width: parseInt(option.width)+'px' }"
:header-cell-class-name="headerCellClassName"
>
<slot name="fixed"></slot>
<el-table-column v-for="(col, index) in tableHeader" :key="index"
:prop="col.prop"
:label="col.label"
:width="col.width"
:min-width="col.minWidth"
:type="col.type"
:header-align="col.headerAlign"
:column-key="index.toString()"
:render-header="renderHeader"
>
</el-table-column>
</el-table>
</div>

上面的 data 是列表数据集合,option 是 Table 组件配置项,header 是表头数据集合,由父组件传入


props: {
data: {
default: function () {
return [] },
type: Array
},
header: {
default: function () {
return [] },
type: Array
},
option: {
default: function () {
return {}
},
type: Object
}
}

配置项可以根据 Element-UI 的 api 自行删减

但有几个参数在组件内部被征用:

1. header-cell-class-name

绑定了一个函数,动态给表头单元格添加 class,从而实现拖动中的虚线效果。

2. column-key

绑定为 header 数组的 index,用于确定需要修改的 header 元素下标

3. render-header

表头渲染函数,用以添加自定义方法,以监听 mousemove 等相关事件 

二、记录拖动状态

拖动过程中需要记录几个关键参数:


data () {
return {
tableHeader: this.header,
dragState: {
start: -1, // 起始元素的 index
end: -1, // 结束元素的 index
move: -1, // 移动鼠标时所覆盖的元素 index