項目碰到一個需求是需要表格字段列進行順序拖拽,查過一些資料,中途也碰到了很多坑,實現方式如下:
封裝成公用組件操作
//父組件 <template> <div> <commonTable :loading="loading" :table-data="priceList" :table-header-tit="tableHeaderTit" :col-table-header-tit="colTableHeaderTit" @columnChange="columnChange" /> </div> </template> <script> import commonTable from '@/layout/components/common/commonTable.vue'; export default { name: 'Table', components: { commonTable }, data() { tableHeaderTit: [], colTableHeaderTit:[], priceList:[], loading:false, }, async mounted() { await this.initHandle(); }, methods:{ initHandle(){ //初始化調用獲取默認用戶表頭數據接口(這邊先用默認數據) this.tableHeaderTit=[ { key: 1, label: '價單編號', field: 'priceCode'}, { key: 2, label: '價單名稱', field: 'priceName' }, { key: 3, label: '幣種', field: 'currency' }, { key: 4, label: '業務類型', field: 'businessTypeName'}, { key: 5, label: '審批狀態', field: 'auditStatusName'}, { key: 6, label: '啟用日期', field: 'startDate' }, { key: 7, label: '截止日期', field: 'endDate'} ]; this.colTableHeaderTit=[ { key: 1, label: '價單編號', field: 'priceCode'}, { key: 2, label: '價單名稱', field: 'priceName' }, { key: 3, label: '幣種', field: 'currency' }, { key: 4, label: '業務類型', field: 'businessTypeName'}, { key: 5, label: '審批狀態', field: 'auditStatusName'}, { key: 6, label: '啟用日期', field: 'startDate' }, { key: 7, label: '截止日期', field: 'endDate'} ] }, columnChange(val) { // 列拖拽操作(改變一次排序遠程存儲一次用戶數據) //調保存用戶接口 } } } </script>
//子組件 commonTable.vue <template> <div class="commonTable"> <el-table ref="table" v-loading="loading" style="width: 100%" class="table-wrap" :data="tableData" height="100%" row-key="item" stripe border header-cell-class-name="header-cell-color" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55" /> <el-table-column v-for="(item, index) in colTableHeaderTit" class-name="allowDrag" :key="`colTableHeaderTit_${index}`" :prop="tableHeaderTit[index].field" :label="item.label" align="center"> </el-table-column> </el-table> </div> </template> <script> import Sortable from 'sortablejs'
//需要下載sortablejs插件
//官方文檔地址:https://github.com/SortableJS/Sortable export default { name:'commonTable', props:['tableData','tableHeaderTit','colTableHeaderTit','loading'], data() { return { } }, mounted() { this.rowDrop() //可拖拽行 this.columnDrop() //可拖拽列 }, methods: { //行拖拽 rowDrop() { const tbody = document.querySelector('.el-table__body-wrapper tbody') const _this = this Sortable.create(tbody, { onEnd({ newIndex, oldIndex }) { const currRow = _this.tableData.splice(oldIndex, 1)[0] _this.tableData.splice(newIndex, 0, currRow) } }) }, //列拖拽 columnDrop() { var _this = this; const wrapperTr = document.querySelector('.el-table__header-wrapper tr') this.sortable = Sortable.create(wrapperTr, { draggable: ".allowDrag",//允許拖拽元素(el-table-column上設置class-name為允許拖拽) animation: 180, delay: 0, //之前調用onEnd方法會出現表格DOM不更新以及表頭對不上的情況所以更換為onUpdate方法 //參考資料 https://www.jianshu.com/p/fd6eb408d8bd onUpdate:function(evt){ //修改items數據順序 var newIndex = evt.newIndex; var oldIndex = evt.oldIndex; const newItem = wrapperTr.children[newIndex]; const oldItem = wrapperTr.children[oldIndex]; // 先刪除移動的節點 wrapperTr.removeChild(newItem) // 再插入移動的節點到原有節點,還原了移動的操作 if(newIndex > oldIndex) { wrapperTr.insertBefore(newItem,oldItem) } else { wrapperTr.insertBefore(newItem,oldItem.nextSibling) } // 更新items數組(index-1是第一列有一個多選列不支持拖拽,否則會有排序錯亂的問題) var item = _this.tableHeaderTit.splice(oldIndex-1,1); _this.tableHeaderTit.splice(newIndex-1,0,item[0]); // 下一個tick就會走patch更新 //每次更新調取保存用戶接口 _this.$emit('columnChange',_this.tableHeaderTit) } }) } } } </script>
參考:https://www.jianshu.com/p/362f880d0bfd
-----END