Element-Ui Table 元件原本是不支援拖拽的,由于實際開發過程中有拖拽功能的需求,從開發角度上來說這種使用第三方元件庫不支援然後自己加功能的方式有 Hack 的嫌疑,稍有不慎,代碼就會越寫越爛,日積月累導緻項目爆炸💥,變得難以維護,如同破窗效應。
Table 支援拖拽功能
vuedraggable
是一個拖拽類元件,底層是他們的
Sortable
庫,有老外對此封裝了一個 NPM Package,根據實際情況取舍是 copy 一個檔案還是 install 一個包。
使用下面的代碼作為一個元件引入,
handle
指定具體的 DOM 元素可拖拽,用于防止
input
無法滑鼠選中的情況。
<template>
<div ref="wrapper">
<div :key="tableKey">
<slot />
</div>
</div>
</template>
<script>
import sortable from 'sortablejs'
export default {
name: 'ElementUiElTableDraggable',
props: {
handle: {
type: String,
default: ''
},
animate: {
type: Number,
default: 100
}
},
data () {
return {
tableKey: 0
}
},
watch: {
tableKey () {
this.$nextTick(() => {
this.makeTableSortAble()
this.keepWrapperHeight(false)
})
}
},
mounted () {
this.makeTableSortAble()
},
methods: {
makeTableSortAble () {
const table = this.$children[0].$el.querySelector(
'.el-table__body-wrapper tbody'
)
sortable.create(table, {
handle: this.handle,
animation: this.animate,
onEnd: ({ newIndex, oldIndex }) => {
this.keepWrapperHeight(true)
this.tableKey = Math.random()
const arr = this.$children[0].data
const targetRow = arr.splice(oldIndex, 1)[0]
arr.splice(newIndex, 0, targetRow)
this.$emit('drop', { targetObject: targetRow, list: arr })
}
})
},
keepWrapperHeight (keep) {
// eslint-disable-next-line prefer-destructuring
const wrapper = this.$refs.wrapper
if (keep) {
wrapper.style.minHeight = `${wrapper.clientHeight}px`
} else {
wrapper.style.minHeight = 'auto'
}
}
}
}
</script>
複制
el-form-item 拖拽
watch: {
uuid () {
this.$nextTick(() => {
this.makeTableSortAble()
this.keepWrapperHeight(false)
})
}
},
mounted () {
this.makeTableSortAble()
}
makeTableSortAble () {
const table = document.querySelector(
'.edit-nested-drag'
)
sortable.create(table, {
handle: '.el-form-item__label',
animation: 100,
onEnd: ({ newIndex, oldIndex }) => {
this.keepWrapperHeight(true)
this.uuid = Math.random()
const targetRow = this.config.tabList.splice(oldIndex, 1)[0]
this.config.tabList.splice(newIndex, 0, targetRow)
// this.$emit('drop', { targetObject: targetRow, list: this.config.tabList })
}
})
},
keepWrapperHeight (keep) {
// eslint-disable-next-line prefer-destructuring
const wrapper = document.querySelector(
'.edit-nested-drag'
)
if (keep) {
wrapper.style.minHeight = `${wrapper.clientHeight}px`
} else {
wrapper.style.minHeight = 'auto'
}
}
複制