sortablejs 拖拽库可看详细配置
//安装
npm install sortablejs --save
//引入
import Sortable from 'sortablejs';
使用
1. 获取要拖动的列表元素 (只要能获取到元素即可)
var el = document.querySelector('.container');
2. 配置
var sortable = Sortable.create(el,{配置内容})
组件封装
//component/sortable.vue
<template>
<div class="sort-table">
<slot :colData="colData" :dropColData="dropColData"/>
</div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
//trClass用于选择要拖动的标签 className指定样式类的元素才允许拖动
props: ['col', 'initFlag', 'trClass', 'className'],
name: 'sortable',
data() {
return {
dropCol: [], // 拖动所需要的th和td,与上面数组一样
isMounted: false,
}
},
mounted() {
this.isMounted = true
if (this.initFlag === undefined || this.initFlag > 0) this.init()
},
computed: {
/* 当前展示的列数组 */
colData() {
let colData = this.col.filter(v => v.label !== '')
return colData
},
/* 要拖动的列数组 */
dropColData() {
let dropColData = this.dropCol.filter(v => v.label !== '')
return dropColData
}
},
methods: {
init() {
if (!this.isMounted) return
/* 阻止默认行为 */
document.body.ondrop = function (event) {
event.preventDefault();
event.stopPropagation();
};
this.columnDrop()
},
/* 列拖拽 */
columnDrop () {
const tr = document.querySelector(this.trClass || '.el-table__header-wrapper tr')
this.sortable = Sortable.create(tr, {
animation: 180, // 过度动画
delay: 0, // 延迟多久可以拖动
filter: ".cannotDrag", // 过滤或忽略指定元素
draggable: this.className, // 指定样式类的元素才允许拖动
onEnd: evt => { // 拖动结束后的事件
const oldItem = this.dropCol[evt.oldIndex]
this.dropCol.splice(evt.oldIndex, 1)
this.dropCol.splice(evt.newIndex, 0, oldItem)
}
})
},
},
watch: {
initFlag: {
immediate: true,
handler(newVal) {
if (newVal === undefined) return this.init()
if (newVal > 0) this.init()
},
},
col: {
deep: true,
immediate: true,
handler(newVal) {
this.dropCol = JSON.parse(JSON.stringify(newVal))
},
},
},
}
</script>
<style lang="scss">
.sort-table {
padding: 0 10px;
.el-input__icon {
line-height: 0;
}
}
</style>
使用
<template>
<sortable
:col="col"
:initFlag="initFlag"
trClass=".table-header-tr"
className=".canDrag"
>
<template slot-scope="sortableScope">
<el-table
:data="Data"
border
style="width: 100%"
>
<el-table-column
class-name="cannotDrag"
type="index"
label="序号"
width="50"
align="center"
></el-table-column>
<el-table-column
v-for="(item, index) in sortableScope.colData"
:key="`col_${index}`"
:prop="sortableScope.dropColData[index].prop"
:label="item.label"
:min-width="item.width"
:class-name="'canDrag_pop'"
align="center"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-link
v-if="sortableScope.dropColData[index].prop === 'address'"
type="primary"
:underline="false"
>{{scope.row.address}}
</el-link>
<template
v-else
type="text"
class="btn-text"
>{{scope.row[sortableScope.dropColData[index].prop]}}
</template>
</template>
</el-table-column>
</el-table>
</template>
</sortable>
</template>
import sortable from '@/components/sortable'
data() {
return {
col: [ // th和对于的td字段
{
label: '', // label为空的表示为序号和checkbox,占位
prop: ''
},
{
label: '姓名',
prop: 'name',
width: '120'
},
{
label: '时间',
prop: 'date',
width: '120'
},
{
label: '地址',
prop: 'address',
width: '120'
}
],
Data: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}]
}
},
computed: {
initFlag() {
if (this.dialogTableVisible) return +new Date()
else return 0
}
}