基于el-table封装的可拖拽行列、选择列组件的实现
2022-04-16 06:04:42 来源:易采站长站 作者:
效果

需要环境
vue
elementUI
拖拽插件Sortable.js
需配置属性

示例
<HTable :columns="columns" :data="list" :setColumn="true" tableKey="CategoriesList" style="width: 100%" border> // 这里可以放插槽 <template slot="create_time" slot-scope="scope"> {{ scope.column.label + scope.item.prop }} </template> <template slot="action" slot-scope="scope"> <el-button type="primary" @click="handleEdit(scope.row)" size="small"> 编辑 </el-button> <el-button @click="handleDelete(scope.row)" type="danger" size="small"> 删除 </el-button> </template></HTable>import HTable from "@/components/HTable";export default { components: { HTable }, data() { return { list: [], columns: [ { label: "ID", // 描述 prop: "_id", // 列的唯一值。 必须要有 checked: true // 是否展示该列 ... // 一些el-table-column的属性都可以写在这里 }, { label: "分类名称", prop: "name", checked: true }, { label: "上级分类", prop: "parent.name", checked: true }, { label: "状态", prop: "status", width: "100", checked: true }, { label: "创建时间", prop: "create_time", slotHeaderName: "create_time", // 自定义表头 checked: true }, { label: "操作", prop: "action", fixed: "right", "min-width": "100", slotName: "action", // 自定义单元格插槽 checked: true, disabled: true } ] }; }};有用到的话给我点个赞!附组件代码
<template> <div class="HTable"> <div class="settingBox" v-if="setColumn"> <el-popover placement="bottom-end" trigger="click" popper-class="settingPopper" > <el-checkbox-group v-model="selectCol" @change="handleChangeSelectColumn" > <el-checkbox v-for="item in col" :key="item.prop" :label="item.prop" :disabled="item.disabled" style="display:block;line-height:2;margin-right:0;" >{{ item.label }}</el-checkbox > </el-checkbox-group> <i class="icon el-icon-setting" slot="reference"></i> </el-popover> </div> <el-table v-bind="$attrs" :data="tableData" v-on="$listeners" :key="JSON.stringify(checkedCol)" > <el-table-column v-for="(item, index) in checkedCol" :key="item.prop" v-bind="item" :index="index" :column-key="item.prop" > <template v-if="item.slotHeaderName" v-slot:header="scope"> <slot :name="item.slotHeaderName" v-bind="scope" :item="item"></slot> </template> <template v-if="item.slotName" v-slot:default="scope"> <slot :name="item.slotName" v-bind="scope"></slot> </template> </el-table-column> </el-table> </div></template><script>import Sortable from "sortablejs";export default { name: "HTable", props: { tableKey: String, columns: { type: Array, default() { return []; } }, data: { type: Array, default() { return []; } }, setColumn: { type: Boolean, default: false } }, watch: { columns: { handler(newVal) { let localVal = this.getStorageCol(); let hotVal = []; if (localVal) { hotVal = this.dataDiff(newVal, localVal); } else { hotVal = [...newVal]; } this.col = hotVal.map( (item, index) => (item = { ...item, index, checked: item.checked || false }) ); this.checkedCol = this.checkedColFun(this.col); this.selectCol = this.checkedCol.map(item => (item = item.prop)); }, immediate: true }, data: { handler(newVal) { this.tableData = [...newVal]; }, immediate: true }, col: { handler(newVal) { this.setStorageCol(newVal); }, deep: true, immediate: true } }, data() { return { tableData: [], col: [], checkedCol: [], selectCol: [] }; }, mounted() { document.body.ondrop = function(event) { event.preventDefault(); event.stopPropagation(); }; this.$nextTick(() => { this.rowDrop(); this.columnDrop(); }); }, methods: { drap() { this.$nextTick(() => { this.rowDrop(); this.columnDrop(); }); }, handleChangeSelectColumn() { this.col.forEach(item => { if (this.selectCol.includes(item.prop)) { item.checked = true; } else { item.checked = false; } }); this.checkedCol = this.checkedColFun(this.col); this.drap(); }, rowDrop() { const tbody = document.querySelector(".el-table__body-wrapper tbody"); Sortable.create(tbody, { onEnd: ({ newIndex, oldIndex }) => { [this.tableData[newIndex], this.tableData[oldIndex]] = [ this.tableData[oldIndex], this.tableData[newIndex] ]; this.drap(); this.$emit("dropRow", { drapRow: this.tableData[oldIndex], targetRow: this.tableData[newIndex], drapRowIndex: oldIndex, targetRowIndex: newIndex, : center; font-size: 20px; line-height: 36px; color: #909399; cursor: pointer; } }}</style><style lang="less">.settingPopper { min-width: 100px !important;}</style>
暂时禁止评论













闽公网安备 35020302000061号