特性
- 可以显示隐藏某一列
- 可以圈选显示隐藏所有列(禁用列不受状态影响)
- 可以拖拽列名进行前后排序
<template> <div :class="$options.name"> <el-dropdown :show-timeout="0" :placement="`bottom`"> <el-link :underline="false" style="cursor: default" >表格列设置 <el-tooltip :enterable="false" effect="dark" :content="`可以上下拖拽改变列顺序`" placement="top" :transition="`none`" > <i class="el-icon-question"></i> </el-tooltip> <i class="el-icon-arrow-down"></i> </el-link> <el-dropdown-menu slot="dropdown" style="transition: none" ><el-dropdown-item> <el-checkbox :indeterminate="checkedHalf" :disabled="!tableColumns.some((v) => !v.disabled)" v-model="checkedAll" @change="changeCheckedAll" @click.native.stop >全选</el-checkbox ></el-dropdown-item > <el-dropdown-item v-for="(item, index) in tableColumns" :key="index" :divided="item.divided" style="padding: 0" > <div :draggable="!item.disabled" style=" padding: 0 20px; box-sizing: border-box; border: 2px dashed transparent; " @dragstart="dragstart($event, index)" @drag="drag" @dragend="dragend" @dragover="dragover" @drop="drop($event, index)" @dragleave="dragleave" > <el-checkbox :disabled="item.disabled" v-model="item.checked" @click.native.stop >{{ item.label }}</el-checkbox > </div></el-dropdown-item > </el-dropdown-menu> </el-dropdown> <el-table :data="tableData"> <el-table-column type="selection" width="50" /> <el-table-column type="index" label="序号" width="60" /> <!-- 主要列 BEGIN---------------------------------------- --> <el-table-column v-for="(a, i) in tableColumns" v-if="a.checked" :key="i" :prop="a.prop" :label="a.label" :width="a.width || `auto`" /> <!-- 主要列 END---------------------------------------- --> <el-table-column label="操作" width="150"> <template slot-scope="scope"> <el-button size="mini" type="primary">修改</el-button> <el-button size="mini" type="danger">删除</el-button> </template> </el-table-column> </el-table> </div> </template> <script> export default { data() { return { // 表格列字段---------------------------------------- checkedHalf: false, checkedAll: false, tableColumns: [ { prop: "ZD1", label: "字段名称1", width: 110 }, { prop: "ZD2", label: "字段名称2", width: 200, checked: true, disabled: true }, { prop: "ZD3", label: "字段名称3", width: 110 }, { prop: "ZD4", label: "字段名称4", width: 110 }, { prop: "ZD5", label: "字段名称5", width: 110 }, ], // ---------------------------------------- tableData: [ { ZD1: "字段1的值-1", ZD2: "字段2的值-1", ZD3: "字段3的值-1", ZD4: "字段4的值-1", ZD5: "字段5的值-1", }, { ZD1: "字段1的值-2", ZD2: "字段2的值-2", ZD3: "字段3的值-2", ZD4: "字段4的值-2", ZD5: "字段5的值-2", }, { ZD1: "字段1的值-3", ZD2: "字段2的值-3", ZD3: "字段3的值-3", ZD4: "字段4的值-3", ZD5: "字段5的值-3", }, { ZD1: "字段1的值-4", ZD2: "字段2的值-4", ZD3: "字段3的值-4", ZD4: "字段4的值-4", ZD5: "字段5的值-4", }, { ZD1: "字段1的值-5", ZD2: "字段2的值-5", ZD3: "字段3的值-5", ZD4: "字段4的值-5", ZD5: "字段5的值-5", }, ], //表格数据 }; }, watch: { tableColumns: { handler(newValue, oldValue) { if (newValue && Object.keys(newValue).length) { this.checkedHalf = newValue.some((v) => v.checked) && newValue.some((v) => !v.checked); //部分选中 newValue.every((v) => v.checked) && ((this.checkedAll = true), (this.checkedHalf = false)); //全选中 this.checkedHalf && (this.checkedAll = false); //未全选中 } }, deep: true, //深度监听 immediate: true, //立即执行 }, }, methods: { changeCheckedAll(checked) { let allowItems = this.tableColumns.filter((v) => !v.disabled); //未被禁用的选项 this.checkedAll = allowItems.some((v) => !v.checked); //在未被禁用的选项中,只要有一个未勾选,点击“全选”就是全选,否者就是全不选 allowItems.forEach((v) => this.$set(v, "checked", this.checkedAll)); }, // 被拖拽物体的监听事件---------------------------------------- dragstart(e, index) { e.dataTransfer.setData("fromIndex", index); //传递拖拽起始位置索引 }, drag(e) { e.currentTarget.style.opacity = 0.618; //被拖拽元素透明 }, dragend(e) { e.currentTarget.style.opacity = 1; //被拖拽元素恢复透明 }, // 放置区域的监听事件---------------------------------------- dragover(e) { let et = e.currentTarget; let lessThanHalf = e.offsetY < et.offsetHeight / 2; //向下拖动鼠标未超过被放置区域一半高度 et.style.borderTopColor = lessThanHalf ? `#409EFF` : `transparent`; //上边线显示 et.style.borderBottomColor = !lessThanHalf ? `#409EFF` : `transparent`; //下边线显示 e.preventDefault(); }, drop(e, index) { let et = e.currentTarget; et.style.borderColor = `transparent`; let lessThanHalf = e.offsetY < et.offsetHeight / 2; //向下拖动鼠标未超过被放置区域一半高度 let fromIndex = e.dataTransfer.getData("fromIndex"); //拖拽起始位置索引 let toIndex = index; //拖拽到的目标位置索引 if (fromIndex == toIndex) return; //一样的位置就不改变顺序了 toIndex = fromIndex < toIndex ? lessThanHalf ? index - 1 : index : lessThanHalf ? index : index + 1; //拖拽到不同的目标位置索引(注意细节:从下往上拖拽 和 从上往下 拖拽索引的大小不一样) this.$g.array.moveArrayElement(this.tableColumns, fromIndex, toIndex); //移动目标元素 }, dragleave(e) { e.currentTarget.style.borderColor = `transparent`; //清空边框线 }, }, }; </script>
应用到了
用第三方插件实现表格的行拖拽排序