element-ui表格很強,但是業務需求更強大,需要表格整列移動,並且整列隱藏
<template> <div> <div class="popoverStyle"> <el-popover placement="bottom" trigger="click"> <el-col :span="20"> <h4>請選擇需要隱藏的內容</h4> </el-col> <el-col :span="12" v-for="(item,index) in _col" :key="index"> <el-checkbox :value="item.isHidden" @change="(val) => {showHide(item, index, val);}" >{{item.label}}</el-checkbox> </el-col> <el-button slot="reference" type="primary" plain class="setting" style="margin:0 5px 0 5px" >設置</el-button> </el-popover> <el-button type="primary" @click="saveAry" plain>保存設置</el-button> </div> <div class="tableCommon"> <el-table max-height="600px" highlight-current-row :data="tableData" tooltip-effect="dark" style="width: 100%" :cell-class-name="cellClassName" :header-cell-class-name="headerCellClassName" @header-dragend="change()" class="drag_table" :row-class-name="tableRowClassName" @selection-change="changeFun" v-loading="loading" element-loading-text="加載中..." :header-cell-style="{background:'rgb(238, 241, 246)',color:'rgb(96, 98, 102)'}" border @row-click="clickSelect" :cell-style="changeColor" > <slot></slot> <el-table-column v-for="(_col, index) in _tableHeader" :key="index" :prop="_col.prop" :label="_col.label" :column-key="index.toString()" :render-header="renderHeader" :show-overflow-tooltip="true" v-if="!col_hide_flat[ index]" min-width="50px" align="center" sortable ></el-table-column> </el-table> </div> </div> </template> <script> import Cookies from "js-cookie"; import { bus } from "../../bus"; import TAPI from "../../api/api_table_define"; import "quill/dist/quill.core.css"; import "quill/dist/quill.snow.css"; import "quill/dist/quill.bubble.css"; export default { name: "table123", props: { tableData: { default: [] }, tableHeader: { default: [] }, col: { default: [] } }, data() { return { clickSelectList: {}, //行點擊 userId: null, tableName: "", _tableHeader: [], _col: [], loading: false, deep_clone_ary: [], col_hide_flat: [], //活動表頭,隱藏表頭 checkBoxData: [], dragState: { startIndex: -1, // 拖動起始元素的index endIndex: -1, // 拖動結showHide束元素的index afterMoveIndex: -1, // 拖動后元素的index dragging: false, // 是否正在拖動 direction: null, // 拖動方向 moveTableOutsideBack: false // 拖出到table外之后又拖回來 }, userInfo: { userId: null, username: "", name: "", enterpriseId: 0, enterpriseName: "" } }; }, methods: { // 行點擊 clickSelect(val) { this.clickSelectList = val; bus.$emit("clickSelect", this.clickSelectList); }, init() { let param = { tableName: this.tableName, userId:this.userId }; TAPI.list(param) .then( rel => { // console.log(rel, 111); if (rel.code == 0 && rel.list.length > 0) { let newtable = []; let table = rel.list; table.forEach(item => { let entity = { prop: item.columnName, label: item.columnComment, isHidden: item.isHidden == 2 ? true : false, checked: item.isHidden == 2 ? true : false }; newtable.push(entity); }); this._tableHeader = newtable; this._col = newtable; // console.log(this._col,3333333333333333); let num = 0; this._tableHeader.forEach(e => { this.$set(this.col_hide_flat, num, e.isHidden); num++; }); } }, err => { this.$message.error({ showClose: true, message: "數據異常", duration: 2000 }); } ) .catch(error => { this.$message.error({ showClose: true, message: "請求出現異常", duration: 2000 }); }); }, saveAry() { this.deep_clone_ary = []; // console.log(this._tableHeader,12121); let num = 1; this._tableHeader.forEach(item => { let entity = { tableName: this.tableName, columnName: item.prop, columnComment: item.label, sort: num, isHidden: item.isHidden == true ? 2 : 1, userId: this.userId }; this.deep_clone_ary.push(entity); num++; }); TAPI.insertBatch(this.deep_clone_ary) .then( result => { if (result.code === 0) { this.$confirm("保存成功", "提示", { type: "success", center: true, showCancelButton: false }); this.init(); this.$message.success({ message: result.msg, duration: 2000 }); } }, err => { this.$message.error({ showClose: true, message: "數據異常", duration: 2000 }); } ) .catch(error => { this.$message.error({ showClose: true, message: "請求出現異常", duration: 2000 }); }); }, changeFun(val) { this.checkBoxData = val; bus.$emit("checkBoxData", this.checkBoxData); }, // 表格隔行變色 tableRowClassName({ row, rowIndex }) { if (rowIndex % 2 === 0) { return "warning-row"; } else { return "success-row"; } }, //隱藏表格頭 showHide(show, _index, val) { this.$set(this.col_hide_flat, _index, val); // console.log(_index, val,'val'); this._tableHeader[_index].isHidden = val; this._col[_index].isHidden = val; return; }, /* * @params: * Description: 表格拖動 */ // drag_table在渲染表頭時調用 renderHeader(h, { column, $index }) { // 這里可以根據$index的值來對自身需求進行修改, return h( "span", { class: ["thead-cell"], style: { // display: "block", // width: "40px", cursor: "move" }, on: { mousedown: $event => { this.handleMouseDown($event, column); }, mouseup: $event => { this.handleMouseUp($event, column); }, mousemove: $event => { this.handleMouseMove($event, column); } } }, [ h("span", [ // 給每個表頭添加icon 可以不需要 h("span"), h("span", column.label) ]), // 給每個表頭添加一個class=virtual 是畫虛線的類名。 h("span", { class: ["virtual"] }) ] ); }, // 按下鼠標開始拖動 設置列的背景色 handleMouseDown(e, column) { // 判斷是鼠標左鍵 if (e.button === 0) { this.dragState.dragging = true; this.dragState.startIndex = parseInt(column.columnKey); // 給當前要拖動列的th設置class document.querySelectorAll(".drag_table table thead tr th")[ this.dragState.startIndex ].className += " " + "dragging_column"; // 給拖動時的虛擬容器添加寬高 let table = document.getElementsByClassName("drag_table")[0]; let virtual = document.getElementsByClassName("virtual"); // 設置新插入的span.virtual的標簽 每一列的寬度、高度 for (let item of virtual) { item.style.height = table.clientHeight - 10 + "px"; item.style.width = item.parentElement.parentElement.clientWidth + "px"; } this.dragState.moveTableOutsideBack = false; } }, // 拖動中 handleMouseMove(e, column) { // 判斷是鼠標左鍵 if (e.button === 0) { if (this.dragState.dragging) { let currentIndex = parseInt(column.columnKey); // 拖動的當前列index if (currentIndex !== this.dragState.startIndex) { this.dragState.direction = currentIndex - this.dragState.startIndex < 0 ? "left" : "right"; // 判斷拖動方向 this.dragState.afterMoveIndex = currentIndex; } else { this.dragState.direction = null; } } else { return false; } } }, // 鼠標放開結束拖動 handleMouseUp(e, column) { // 判斷是鼠標左鍵 if (e.button === 0) { // 拖出當前table外之后又拖回來,不再進行易位操作(拖出去時已處理) if (this.dragState.moveTableOutsideBack) { return false; } else { this.dragState.endIndex = parseInt(column.columnKey); // 記錄結束列index if (this.dragState.startIndex !== this.dragState.endIndex) { this.dragColumn(this.dragState); } this.finishDragInit(); } } // console.log(this.dragState.endIndex, 'drageStar') }, // 拖動到當前table之外的處理 moveTableOutside() { if (this.dragState.dragging) { this.dragState.endIndex = this.dragState.startIndex; if (this.dragState.startIndex !== this.dragState.endIndex) { this.dragColumn(this.dragState); } this.finishDragInit(); this.dragState.moveTableOutsideBack = true; } }, // 拖動易位 dragColumn({ startIndex, endIndex, direction }) { // 排除掉鼠標點擊table外面,然后拖入進table報錯 if (startIndex < 0) { return; } // 判斷是向左移動還是向右移動 // 把移動的列插在某個列前面或者后面,然后在刪除移動的列 if (direction === "left") { this._tableHeader.splice(endIndex, 0, this._tableHeader[startIndex]); this._tableHeader.splice(startIndex + 1, 1); } else { this._tableHeader.splice( endIndex + 1, 0, this._tableHeader[startIndex] ); this._tableHeader.splice(startIndex, 1); } // console.log(startIndex, ';endIndex'); // console.log(startIndex, ';endIndex'); }, // 拖動完成后的初始化 finishDragInit() { // 給當前要拖動列的th取消class for (var item of document.querySelectorAll( ".drag_table table thead tr th" )) { item.className = String(item.className) .split("dragging_column") .join(""); } // 再次初始化拖動狀態 this.dragState = { startIndex: -1, endIndex: -1, afterMoveIndex: -1, dragging: false, direction: null, moveTableOutsideBack: false }; }, headerCellClassName({ column, columnIndex }) { return columnIndex === this.dragState.afterMoveIndex ? `drag_active_${this.dragState.direction}` : ""; }, // 動態給表頭單元格th添加class,實現拖動中的背景 cellClassName({ column, columnIndex }) { return columnIndex === this.dragState.startIndex ? `dragging_column` : ""; }, change() {}, //改變顏色 changeColor(row, column, rowIndex, columnIndex) { if ( (row.column.label == "證照狀態" && row.row.certificateStatus == "3") || (row.column.label == "證照狀態" && row.row.certificateStatus == "1") || (row.column.label == "審核狀態" && row.row.auditStatus == '3')|| (row.column.label == "使用狀態" && row.row.status == '2')|| (row.column.label == "耗材狀態" && row.row.consumeStatus == '2')|| (row.column.label == "證照狀態" && row.row.authorizationStatus == '3')|| (row.column.label == "證照狀態" && row.row.authorizationStatus == '1')|| (row.column.label == "證照狀態" && row.row.proxyStatus == '3')|| (row.column.label == "證照狀態" && row.row.proxyStatus == '1')|| (row.column.label == "審核狀態" && row.row.verifyStatus == '3')|| (row.column.label == "審核狀態" && row.row.verifyStatus == '3')|| (row.column.label == "供應關系狀態" && row.row.supplierrelationshipstatus == '2')|| (row.column.label == "供應關系狀態" && row.row.materialrelationshipstatus == '2')|| (row.column.label == "狀態" && row.row.status == '2')|| (row.column.label == "消息狀態" && row.row.status == '2')|| (row.column.label == "發布狀態" && row.row.status == '3')|| (row.column.label == "推送狀態" && row.row.messageStatus == '3') ) { return "color:red"; }else { } }, }, created() { this.col_hide_flat.length = 100; this._tableHeader = this.tableHeader; this._col = this.col; }, mounted() { this.userInfo = JSON.parse(Cookies.get("userInfo")); this.userId = this.userInfo.userId; this.tableName = this.$route.path .substring(11) .replace(/\//g, "-") .replace(/\+/g, "-"); this.init(); } }; </script> <style> .popoverStyle { /*display: flex;*/ /*border: 1px solid red;*/ display: block; margin-bottom: 10px; } .el-table__body tr.current-row > td { #fca454 !important; color: #333333; } .tableCommon { width: 100%; } </style>
引入表格使用
import myTable from "../commonComponents/table"; components: { "my-table": myTable }, <my-table :table-data="表格數據" :tableHeader="tableHeader" :col="col"></my-table>
//表格頭 tableHeader: [ { label: "流水", prop: "productCode", showif: "show_productCode", isHidden: false }, { label: "最", prop: "most", showif: "show_most", isHidden: false }, { label: "時間", prop: "time", showif: "show_time", isHidden: false } ],
//隱藏頭 col: [ { label: "流水", prop: "productCode", showif: "show_productCode", isHidden: false }, { label: "最", prop: "most", showif: "show_most", isHidden: false }, { label: "時間", prop: "time", showif: "show_time", isHidden: false } ]