需求:vue+element-ui+sortable.js表格行和列拖拽(宽度自定义)
一、效果图
二、代码实现
注:需要安装依赖 pnpm i sortablejs -S
<template> <div style="padding: 15px"> <h3 style="text-align: left; padding: 10px; background: #ccc"> vue+element-ui+sortable.js表格行和列拖拽 </h3> <!-- 属性border可实现单元格拖拽获得字段宽度的改变--`@header-dragend`具体参考官网的方法 --> <el-table ref="dataTable" :data="customColumnList" class="customer-table" border row-key="id" align="left" @select="handleSelectionChange" > <el-table-column type="selection" :selectable="checkSelectable" align="center" width="55" ></el-table-column> <el-table-column prop="label" label="字段名" width="180"> <template slot-scope="scope"> {{ scope.row.label }} </template> </el-table-column> <el-table-column prop="width" label="宽度" width="180"> <template slot-scope="scope"> <div class="right-box"> <p style="padding-right: 5px">宽度</p> <el-input style="width: 60px" size="mini" type="text" v-model="scope.row.width" @keyup.enter.native="this.rowDrop()" ></el-input> <p style="padding-left: 5px">px</p> </div> </template> </el-table-column> </el-table> </div> </template>
<script> import Sortable from "sortablejs"; export default { name: "login", data() { return { customColumnList: [ { id: 1, label: "linger1", width: "220", }, { id: 2, label: "linger2", resizable: false, width: "70", }, { id: 3, label: "linger3", width: "150", }, { id: 4, label: "linger4", width: "120", resizable: false, }, { id: 5, label: "linger5", width: "200", resizable: false, }, ], hasSelectList: [1, 5, 2], }; }, mounted() { this.getTableData(); this.rowDrop(); }, methods: { getTableData() { // 默认选中 this.$nextTick(() => { this.customColumnList.forEach((row) => { if (this.hasSelectList.indexOf(row.id) >= 0) { this.$refs.dataTable.toggleRowSelection(row, true); } }); }); }, // 监听复选框的选择 handleSelectionChange(section) { this.hasSelectList = section.map((item) => item.id); const List = this.customColumnList.filter((item) => section.map((items) => items.id).some((_item) => item.id === _item) ); // 排序后的列表 console.log(List); // console.log(this.hasSelectList); }, // 设置失效的行数id=5不可勾选 checkSelectable(row) { if (row.id !== 5) { return true } }, //行拖拽 rowDrop() { const tbody = document.querySelector(".el-table__body-wrapper tbody"); const _this = this; Sortable.create(tbody, { onEnd({ newIndex, oldIndex }) { const currRow = _this.customColumnList.splice(oldIndex, 1)[0]; _this.customColumnList.splice(newIndex, 0, currRow); console.log(_this.customColumnList); }, }); console.log(_this.customColumnList); }, //列拖拽 // columnDrop() { // const wrapperTr = document.querySelector(".el-table__header-wrapper tr"); // console.log("wrapperTr:", wrapperTr); // this.sortable = Sortable.create(wrapperTr, { // animation: 180, // delay: 0, // handle: ".move", // 只有带move类名的元素才能拖动,多选框禁止拖动 // onEnd: (evt) => { // // 因为手动加了一个多选框, 不在表头循环数组内, 所以这里减1 // let oldIndx = evt.oldIndex - 1; // let newIndx = evt.newIndex - 1; // const oldItem = this.dropCol[oldIndx]; // // 真正改变列数据--变化列头,就能实现列拖动 列数据按列头索引取值 {{ scope.row[dropCol[index].prop] }} // this.dropCol.splice(oldIndx, 1); // 删除旧一行 删除为1 // this.dropCol.splice(newIndx, 0, oldItem); // 插入新一行 插入为0 // }, // }); // }, }, }; </script>
<style scoped> .right-box { display: flex; justify-content: center; align-items: center; } </style> <style> /* 取消单元格的列的border */ .el-table--border .el-table__cell { border: none; } .el-table--border, .el-table--group { border: none; } /* 去掉表格单元格边框 */ /* 头部边框设置 */ /* 表格最外边框 */ .el-table--border, .el-table--group { border: none; } .customer-table thead tr th.is-leaf{ border: 1px solid #EBEEF5; border-right: none; } .customer-table thead tr th:nth-last-of-type(2){ border-right: 1px solid #EBEEF5; } </style>