EffectNeed environment vue Required configuration properties Example<HTable :columns="columns" :data="list" :setColumn="true" tableKey="CategoriesList" style="width: 100%" border > // You can put slots here <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"> Edit</el-button> <el-button @click="handleDelete(scope.row)" type="danger" size="small"> Delete</el-button> </template> </HTable> import HTable from "@/components/HTable"; export default { components: { HTable }, data() { return { list: [], columns: [ { label: "ID", // description prop: "_id", // The unique value of the column. Must have checked: true // Whether to display this column... // Some el-table-column attributes can be written here}, { label: "category name", prop: "name", checked: true }, { label: "Superior Category", prop: "parent.name", checked: true }, { label: "status", prop: "status", width: "100", checked: true }, { label: "Creation time", prop: "create_time", slotHeaderName: "create_time", // Custom header checked: true }, { label: "operation", prop: "action", fixed: "right", "min-width": "100", slotName: "action", // Custom cell slot checked: true, disabled: true } ] }; } }; Give me a thumbs up if it’s useful! Attached component code <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, data: this.tableData }); } }); }, columnDrop() { const wrapperTr = document.querySelector(".el-table__header-wrapper tr"); Sortable.create(wrapperTr, { animation: 180, delay: 0, onEnd: ({ newIndex, oldIndex }) => { const oldItem = this.checkedCol[oldIndex]; const newItem = this.checkedCol[newIndex]; [this.col[newItem.index].index, this.col[oldItem.index].index] = [ oldItem.index, newItem.index ]; this.col.sort((a, b) => { return a.index - b.index; }); this.checkedCol = this.checkedColFun(this.col); this.tableData = this.tableData.slice(0, this.tableData.length); this.drap(); this.$emit("dropCol", { colItem: oldItem, newIndex: newIndex, oldIndex: oldIndex, column: this.checkedCol }); } }); }, checkedColFun(arr) { return arr.filter(item => item.checked); }, setStorageCol(data) { if (this.tableKey && data && data.length > 0) { localStorage.setItem("HTable-" + this.tableKey, JSON.stringify(data)); } }, getStorageCol() { let datajson = localStorage.getItem("HTable-" + this.tableKey); return datajson ? JSON.parse(datajson) : ""; }, dataDiff(newVal, localVal) { let nl = newVal.length; let ll = localVal.length; if (nl != ll) { return newVal; } else { let np = newVal.map(item => item.prop).sort(); let lp = localVal.map(item => item.prop).sort(); if (np.join() != lp.join()) { return newVal; } else { let nnl = []; for (let i = 0; i < localVal.length; i++) { const item_l = localVal[i]; for (let j = 0; j < newVal.length; j++) { const item_n = newVal[j]; if (item_l.prop === item_n.prop) { nnl.push({ ...item_n, index: item_l.index }); } } } return nnl; } } } } }; </script> <style lang="less" scoped> .HTable { position: relative; .settingBox { width: 36px; height: 36px; border-radius: 2px; border: 1px solid #ebeef5; border-bottom: 0; margin-left: auto; position: relative; .icon { position: absolute; top: 0; left: 0; z-index: 1; width: 36px; height: 36px; text-align: center; font-size: 20px; line-height: 36px; color: #909399; cursor: pointer; } } } </style> <style lang="less"> .settingPopper { min-width: 100px !important; } </style> This is the end of this article about the implementation of draggable rows and columns and selection column components based on el-table encapsulation. For more relevant el-table draggable rows and columns, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: 【HTML element】How to embed images
>>: Comprehensive summary of MYSQL tables
Restart all stopped Docker containers with one co...
Here are some tips from training institutions and...
Chapter 1: Introduction to keepalived The purpose...
Copy code The code is as follows: <object clas...
Table of contents Multiple conditional statements...
This work uses the knowledge of front-end develop...
Content 1. Give readers a reason to stay. Make the...
nbsp   no-break space = non-breaking spa...
Table of contents MySQL case sensitivity is contr...
First, install PHP5 very simple yum install php T...
Table of contents 1. Teleport 1.1 Introduction to...
Table of contents 1. What is a hook? 2. Why does ...
Table of contents Vue3 encapsulation message prom...
Copy code The code is as follows: <head> &l...
Stored Procedures 1. Create a stored procedure an...