最近接到一个表格拖拽并改变排序的需求
那么首先需要实现表格拖拽
一.引入第三方插件
1.引入sortable.js的包: npm install sortable.js --save
2.或者npm i -S vuedraggable
vuedraggable依赖 Sortable.js,所以下载了vuedraggable,我们便可以直接引入Sortable使用Sortable的特性。
vuedraggable是Sortable一种加强,实现组件化的思想,可以结合Vue,使用起来更方便
二.使用sortable
以sortable为例子,在我们需要使用sortable的文件中
import Sortable from 'sortablejs'
三.代码展示
如果要使用sortable,那么element table务必指定row-key,并且row-key必须是唯一的,如ID,不然会出现排序不对的情况,一般情况下浏览器会直接报错。
1.html布局
<el-table
size='small'
:data='videoTable'
style='width:100%'
row-key='sn'
@cell-mouse-enter.once='rowDrop'
:row-class-name='rowClassName'
>
<el-table-column width='50'>
<i class='el-icon-s-operation' style='font-size: 14px'></i>
</el-table-column>
<el-table-column prop='ordering' label='序号' width='50' type='index'></el-table-column>
<el-table-column prop='sn' label='内容ID' min-width='120'></el-table-column>
<el-table-column prop='title' label='内容标题' min-width='120'></el-table-column>
<el-table-column prop='fileSize' label='大小' min-width='80'>
<template slot-scope='scope'>
<span>{{ scope.row.fileSize }}M</span>
</template>
</el-table-column>
<el-table-column min-width='80'>
<template slot-scope='scope'>
<el-button type='text' size='small' @click='deleteVideo(scope.row)'>删除</el-button>
</template>
</el-table-column>
</el-table>
因为需要,我代码中使用得是sn,但同id一样也是唯一的
因为要排序,所以应用了element-ui table组件的Table-column Attributes: type
当type=index时,会通过传递index属性来自定义索引,从1开始,这样每次拖拽之后都会重新自动排序
2.核心js
//行拖拽
methods: {
rowDrop() {
const tbody = document.querySelector('.el-table__body-wrapper tbody')
const self = this
Sortable.create(tbody, {
onEnd({ newIndex, oldIndex }) {
const currRow = self.tableData.splice(oldIndex, 1)[0]
self.tableData.splice(newIndex, 0, currRow)
}
})
},
//列拖拽
columnDrop() {
const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: evt => {
const oldItem = this.dropCol[evt.oldIndex]
this.dropCol.splice(evt.oldIndex, 1)
this.dropCol.splice(evt.newIndex, 0, oldItem)
}
})
},
},
mounted() {
this.rowDrop()
this.columnDrop()
},
注意
在这里我遇到了一个问题,就是他会报出一个错误,大致原因就是因为table中的数组内容还未渲染完成就调用了拖拽的方法,没有el元素去支持这个方法的运行
这里我以拖拽行为例,因为我只用到了拖拽行,当我console.log(tbody)
发现此时输出的并不是table的数据,而是null
解决方案
1.我使用的解决方案之一便是刚开始不调用拖拽的方法,使用el-table内置的方法@cell-mouse-enter.once='rowDrop'
当进入到表格的每一个column中都会触发这个方法,但是这样做会导致我们多次调用这个方法,浪费资源,所以这是需要once来让此方法只调用一次,如果不太懂once的作用可以去vue文档中看一下。
2.这个方法就更容易理解setTimeout
,延缓一段时间再去执行,数据渲染的时间是很快的,所以设置的时间也不宜过长,我设置了300ms,虽然可能还不是最短时间,但是刚好也不会影响接下来的操作。
参考http://www.cnblogs.com/jin-zhe/p/10181852.html