Vue table表單拖拽
業務需求:
因為數據展示使用的是 elementUI 的 Table進行數據展示的,現在的需求是通過拖拽表單進行表單排序。同時,動態修改表單中的數據排列順序。查閱了好多資料,也翻看了好多github上別人封裝好的表單插件,但是最終都不是自己想要的,其中主要原因就是,后台管理系統頁面中,同一個窗口可能涉及到多個表單拖拽排序,與此同時,使用部分插件就有可能導致數據更新不及時,或者下次在使用的時候,數據無論如何賦值就是更新不成功,導致最終渲染的要拖拽的表單一會有數據,一會無數據的,體驗很不好。
解決方案:
選取了好多封裝好的插件,都沒有達到自己想要的效果。偶然間看到有人提示使用原生拖拽的方式來解決表單托拖拽排序的問題。最終,我采用 sortablejs 結合原生DOM節點操作的方式,對表單元素數據進行剪切、拼接處理等方式,最終達到理想效果。
操作步驟:
- 首先安裝 sortablejs 插件
yarn add sortablejs
- 引用 sortablejs 插件(全局使用,或組件內使用)
import Sortable from "sortablejs";
- Table 相關代碼
<template>
<div class="drag_table">
<!-- row-key 排序依據的參數,此處不能使用 index 作為排序的依據 -->
<!-- highlight-current-row:單擊選中行高亮 -->
<el-table :data="dragList" ref="dragTable" row-key="id" border stripe highlight-current-row>
<el-table-column label="序號" type="index" width="50" align="center"></el-table-column>
<el-table-column label="ID" prop="id" align="center"></el-table-column>
<el-table-column label="姓名" prop="name" show-overflow-tooltip></el-table-column>
<!-- 性別判斷,使用 prop 屬性 -->
<el-table-column label="性別" prop="sex">
<template slot-scope="scope">
<el-tag>{{ scope.row.sex === 0 ? '女' : '男' }}</el-tag>
</template>
</el-table-column>
<!-- 從排序表單中移除表單元素 -->
<el-table-column label="操作" width="66" align="center">
<template slot-scope="scope">
<el-button type="danger" icon="el-icon-delete" plain @click="delItem(scope.$index)">移除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
- JavaScript邏輯代碼
// 引入排序插件
import Sortable from "sortablejs";
export default {
name: "DragTable",
data() {
return {
sortable: null /* 表單拖拽 */ ,
dragList: [{
id: 1,
name: '張三',
sex: 1
}, {
id: 2,
name: '李四',
sex: 0
}, {
id: 3,
name: '王五',
sex: 0
}, {
id: 4,
name: '趙六',
sex: 1
}]
}
},
mounted() {
// 等待數據渲染完成再加初始化拖拽表單
this.$nextTick(() => {
this.initSortTable();
});
},
methods: {
// 移除數據
delItem(index) {
this.dragList.splice(index, 1)
},
// 初始化拖拽表單
initSortTable() {
// const elTag = this.$refs['dragTable'].$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];
// 獲取 el-table
const tableTag = this.$refs['dragTable'].$el;
// 獲取 tbody 節點
const elTbody = tableTag.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];
// 拖拽排序
this.sortable = Sortable.create(elTbody, {
onEnd: evt => {
const tempIndex = this.dragList.splice(evt.oldIndex, 1)[0];
this.dragList.splice(evt.newIndex, 0, tempIndex);
}
});
}
},
}