赞
踩
实现Element UI中的el-table表格组件的行和列的拖拽排序
使用
Vue3 + Element Plus UI + sortablejs
安装sortablejs
pnpm install sortablejs
效果
<script setup> import { onMounted, ref } from "vue"; import Sortable from "sortablejs"; const tableData = ref([ { id: 1, date: "2016-05-02", name: "王小虎111", age: 21, address: "上海市普陀区金沙江路 1518 弄", }, { id: 2, date: "2016-05-04", name: "王小虎222", age: 22, address: "上海市普陀区金沙江路 1517 弄", }, { id: 3, date: "2016-05-01", name: "王小虎333", age: 23, address: "上海市普陀区金沙江路 1519 弄", }, { id: 4, date: "2016-05-03", name: "王小虎444", age: 24, address: "上海市普陀区金沙江路 1516 弄", }, { id: 5, date: "2016-05-08", name: "王小虎555", age: 25, address: "上海市普陀区金沙江路 1518 弄", }, ]); onMounted(() => { rowDrop(); }); /** * 行拖拽排序 */ function rowDrop() { // 要侦听拖拽响应的DOM对象 const tbody = document.querySelector(".el-table__body-wrapper tbody"); const data = tableData.value; Sortable.create(tbody, { // handle: ".el-icon-rank", ghostClass: "target-row-class", // 结束拖拽后的回调函数 onEnd({ newIndex, oldIndex }) { // 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位 const currentRow = data.splice(oldIndex, 1)[0]; // 将被删除元素插入到新位置(currRow表示上面的被删除数据) data.splice(newIndex, 0, currentRow); }, }); } </script> <template> <el-table ref="table" :data="tableData" style="width: 100%" border row-key="id" > <el-table-column prop="date" label="日期" /> <el-table-column prop="name" label="姓名" /> <el-table-column prop="age" label="年龄" /> <el-table-column prop="address" label="地址" /> <!--<el-table-column align="center" width="55">--> <!-- <i class="el-icon-rank" />--> <!--</el-table-column>--> </el-table> </template> <style scoped lang="less"> .el-table { ::v-deep { .target-row-class { background: #f0f9eb; } } } </style>
效果
<script setup> import { onMounted, ref } from "vue"; import Sortable from "sortablejs"; const tableData = ref([ { id: 1, date: "2016-05-02", name: "王小虎111", age: 21, address: "上海市普陀区金沙江路 1518 弄", }, { id: 2, date: "2016-05-04", name: "王小虎222", age: 22, address: "上海市普陀区金沙江路 1517 弄", }, { id: 3, date: "2016-05-01", name: "王小虎333", age: 23, address: "上海市普陀区金沙江路 1519 弄", }, { id: 4, date: "2016-05-03", name: "王小虎444", age: 24, address: "上海市普陀区金沙江路 1516 弄", }, { id: 5, date: "2016-05-08", name: "王小虎555", age: 25, address: "上海市普陀区金沙江路 1518 弄", }, ]); onMounted(() => { rowDrop(); }); /** * 行拖拽排序 */ function rowDrop() { // 要侦听拖拽响应的DOM对象 const tbody = document.querySelector(".el-table__body-wrapper tbody"); const data = tableData.value; Sortable.create(tbody, { // handle: ".el-icon-rank", ghostClass: "target-row-class", // 匹配的元素将不会触发拖动 filter: ".filtered", // 拖拽移动事件,返回false取消移动 onMove: function ({ related }) { return related.className.indexOf("filtered") === -1; }, // 结束拖拽后的回调函数 onEnd({ newIndex, oldIndex }) { // 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位 const currentRow = data.splice(oldIndex, 1)[0]; // 将被删除元素插入到新位置(currRow表示上面的被删除数据) data.splice(newIndex, 0, currentRow); }, }); } // 设置ID为1和5的行禁止拖拽 function tableRowClassName({ row, rowIndex }) { const freezeList = [1, 5]; return freezeList.includes(row.id) ? "filtered" : ""; } </script> <template> <el-table ref="table" :data="tableData" style="width: 100%" border row-key="id" :row-class-name="tableRowClassName" > <el-table-column prop="date" label="日期" /> <el-table-column prop="name" label="姓名" /> <el-table-column prop="age" label="年龄" /> <el-table-column prop="address" label="地址" /> <!--<el-table-column align="center" width="55">--> <!-- <i class="el-icon-rank" />--> <!--</el-table-column>--> </el-table> </template> <style scoped lang="less"> .el-table { ::v-deep { .target-row-class { background: #f0f9eb; } // 禁止拖拽行背景色 .filtered { background-color: #1db1e7 !important; } } } </style>
效果
<script setup> import { onMounted, ref } from "vue"; import Sortable from "sortablejs"; const columns = ref([ { label: "日期", prop: "date" }, { label: "姓名", prop: "name" }, { label: "年龄", prop: "age" }, { label: "地址", prop: "address" }, ]); const tableData = ref([ { id: 1, date: "2016-05-02", name: "王小虎111", age: 21, address: "上海市普陀区金沙江路 1518 弄", }, { id: 2, date: "2016-05-04", name: "王小虎222", age: 22, address: "上海市普陀区金沙江路 1517 弄", }, { id: 3, date: "2016-05-01", name: "王小虎333", age: 23, address: "上海市普陀区金沙江路 1519 弄", }, { id: 4, date: "2016-05-03", name: "王小虎444", age: 24, address: "上海市普陀区金沙江路 1516 弄", }, { id: 5, date: "2016-05-08", name: "王小虎555", age: 25, address: "上海市普陀区金沙江路 1518 弄", }, ]); onMounted(() => { columnDrop(); }); /** * 列拖拽排序 */ function columnDrop() { // 要侦听拖拽响应的DOM对象 const wrapperTr = document.querySelector(".el-table__header-wrapper tr"); Sortable.create(wrapperTr, { animation: 180, delay: 0, onEnd({ newIndex, oldIndex }) { const draggedItem = columns.value.splice(oldIndex, 1)[0]; columns.value.splice(newIndex, 0, draggedItem); }, }); } </script> <template> <el-table ref="table" :data="tableData" style="width: 100%" border row-key="id" > <el-table-column v-for="(column, index) in columns" :key="index" :prop="column.prop" :label="column.label" /> </el-table> </template>
效果
<script setup> import { onMounted, ref } from "vue"; import Sortable from "sortablejs"; const columns = ref([ { label: "日期", prop: "date" }, { label: "姓名", prop: "name", draggable: true }, { label: "年龄", prop: "age", draggable: true }, { label: "地址", prop: "address" }, ]); const columnsDrop = ref([ { label: "日期", prop: "date" }, { label: "姓名", prop: "name" }, { label: "年龄", prop: "age" }, { label: "地址", prop: "address" }, ]); const tableData = ref([ { id: 1, date: "2016-05-02", name: "王小虎111", age: 21, address: "上海市普陀区金沙江路 1518 弄", }, { id: 2, date: "2016-05-04", name: "王小虎222", age: 22, address: "上海市普陀区金沙江路 1517 弄", }, { id: 3, date: "2016-05-01", name: "王小虎333", age: 23, address: "上海市普陀区金沙江路 1519 弄", }, { id: 4, date: "2016-05-03", name: "王小虎444", age: 24, address: "上海市普陀区金沙江路 1516 弄", }, { id: 5, date: "2016-05-08", name: "王小虎555", age: 25, address: "上海市普陀区金沙江路 1518 弄", }, ]); // 定义变量来记录固定列的class名 const fixedColumnClass = "filtered"; onMounted(() => { columnDrop(); }); function setHeaderCellClass({ column }) { const columnLabels = columns.value .filter((column) => column.draggable) .map((column) => column.label); return !columnLabels.includes(column.label) ? fixedColumnClass : ""; } /** * 列拖拽排序 */ function columnDrop() { // 要侦听拖拽响应的DOM对象 const wrapperTr = document.querySelector(".el-table__header-wrapper tr"); Sortable.create(wrapperTr, { animation: 180, delay: 0, ghostClass: "target-row-class", filter: `.${fixedColumnClass}`, // filter: (event, item) => { // // 也可以根据item的类名、id或其他属性来决定是否应该被排除 // return !item.classList.contains("draggable"); // }, onMove: function ({ related }) { return related.className.indexOf(fixedColumnClass) === -1; }, onEnd({ newIndex, oldIndex }) { const draggedItem = columnsDrop.value.splice(oldIndex, 1)[0]; columnsDrop.value.splice(newIndex, 0, draggedItem); }, }); } </script> <template> <el-table ref="table" :data="tableData" style="width: 100%" border row-key="id" :header-cell-class-name="setHeaderCellClass" > <el-table-column v-for="(column, index) in columns" :key="column.prop" :prop="columnsDrop[index].prop" :label="column.label" /> </el-table> </template> <style scoped lang="less"> .el-table { ::v-deep { .target-row-class { background: #f0f9eb; } .filtered { background-color: #1db1e7 !important; } } } </style>
未完待续
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。