vue+element-ui+sortable.js实现表格行和列的拖拽
项目碰到一个需求是需要表格字段列进行顺序拖拽,查过一些资料,中途也碰到了很多坑,实现方式如下:
封装成公用组件操作
//父组件 <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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了