下述代碼為組件實現代碼複製即可食用,預設只展示 一屏數據加兩條 全選存在些許問題, 使用row-key時,如果行過多滾動時會不會很流暢 特別需要註意的是 行高必須要保持一致 <template> <div class="t-table" :id="TTableId"> <el-table ref=" ...
下述代碼為組件實現代碼複製即可食用,預設只展示 一屏數據加兩條
全選存在些許問題, 使用row-key時,如果行過多滾動時會不會很流暢
特別需要註意的是 行高必須要保持一致
<template> <div class="t-table" :id="TTableId"> <el-table ref="el-table" :tooltip-effect="tooltipEffect" :data="tableData" border :height="height" :row-class-name="rowClassName" :key="tableKey" :row-key="getRowKey" @select-all=" val => { this.selectAll(val, !isAll); } " @select="select" @current-change="handleCurrentChange" :highlight-current-row="highlightCurrentRow" :header-cell-style="headerCellStyle" :cell-style="cellStyle" :empty-text="emptyText" @row-click=" (row, column, event) => this.rowClick(row, column, event, 'table') " > <el-table-column type="index" v-if="index" align="center" fixed> <template slot-scope="scope"> {{ start > 0 ? scope.$index + start + 1 : scope.$index + 1 }} </template> </el-table-column> <el-table-column type="selection" fixed :reserve-selection="true" :width="$TableWidth.px46" v-if="selection" :selectable="rowSelectable" ></el-table-column> <slot></slot> </el-table> </div> </template> <script> export default { components: { }, name: "TTable", props: { //表格數據列表 saveDATA: { typeof: Array, default: [] }, //表格高度 height: { typeof: Number, default: 400 }, //一行高度 為了計算高度,需要行高固定且不能出現換行數據 itemHeight: { typeof: Number, default: 49 }, rowClassName: { typeof: Function, default: () => {} }, tooltipEffect: { typeof: String, default: "" }, //行key 必須填寫saveDATA裡面的變數名 rowKey: { typeof: String, default: "" }, //是否顯示覆選框列 selection: { typeof: Boolean, default: false }, //是否顯示序號列 index: { typeof: Boolean, default: false }, //行禁選方法 rowSelectable: { typeof: Function, default: () => {} }, //是否可以單選 highlightCurrentRow: { typeof: Boolean, default: false }, //表頭樣式 headerCellStyle: { typeof: Object }, //表格樣式 cellStyle: { typeof: Object }, //無數據文字 emptyText: { typeof: String, default: "" }, colDisable: { typeof: Array }, //組件id 如果一個頁面需要使用多個ttable組件 需要給此參數賦唯一值 TTableId: { typeof: String, default: "t_table" } }, data() { return { tableData: [], //展示數據列表 tableRef: null, // 設置了滾動的那個盒子 tableWarp: null, // 被設置的transform元素 fixLeft: null, // 固定左側--設置的transform元素 fixRight: null, // 固定右側--設置的transform元素 tableFixedLeft: null, // 左側固定列所在的盒子 tableFixedRight: null, // 右側固定列所在的盒子 scrollTop: 0, //滾動高度 scrollNum: 0, //當前滾動了幾屏數據 scrollTop / (itemHeight * pageList) scrollRowNum: 0, //記錄當前滾動了多少條數據 start: 0, //預設截取數據開始位數 end: this.pageList + 2, //預設截取數據結束位數 selectList: [], //當前選中的列表 isAll: false, //是否全選 tableKey: "", //表格key currentRow: "", //單選數據 }; }, watch: { //每滾動一條數據則更改展示數據源並且更改容器偏移量 scrollRowNum(newV) { this.start = newV - 1; this.end = this.pageList + newV + 1; if (this.start <= 0) this.start = 0; this.tableData = this.saveDATA.slice(this.start, this.end); if (this.currentRow) this.setCurrentRow(this.currentRow); requestAnimationFrame(() => { // 計算偏移量 let translateY = `translateY(${this.start * this.itemHeight}px)`; this.tableWarp.style.transform = translateY; if (this.fixLeft) { this.fixLeft.style.transform = translateY; } if (this.fixRight) { this.fixRight.style.transform = translateY; } this.doLayout(); }); }, saveDATA: { handler(val) { this.init(); this.initMounted(); }, deep: true // 深度監聽 }, pageList() { this.init(); this.initMounted(); } }, created() { }, mounted() { this.$nextTick(() => { this.tableSetRef = this.GetTableRef(); }); }, methods: { clearIndex() { this.start = 0; this.end = this.pageList + 2; this.scrollNum = 0; if (this.tableRef) this.tableRef.scrollTop = 0; }, //初始化表格內容盒子 initMounted() { this.$nextTick(() => { let box = document.getElementById(this.TTableId); // 設置了滾動的盒子 this.tableRef = this.$refs["el-table"].bodyWrapper; // 左側固定列所在的盒子 this.tableFixedLeft = box.querySelector( ".el-table .el-table__fixed .el-table__fixed-body-wrapper" ); // 右側固定列所在的盒子 this.tableFixedRight = box.querySelector( ".el-table .el-table__fixed-right .el-table__fixed-body-wrapper" ); /** * fixed-left | 主體 | fixed-right */ // 創建內容盒子divWarpPar並且高度設置為所有數據所需要的總高度 let dwp = box.getElementsByClassName("divWarpPar")[0]; if (dwp) { dwp.style.height = this.saveDATA.length * this.itemHeight + "px"; } else { let divWarpPar = document.createElement("div"); divWarpPar.className = "divWarpPar"; // 如果這裡還沒獲取到saveDATA數據就渲染會導致內容盒子高度為0,可以通過監聽saveDATA的長度後再設置一次高度 divWarpPar.style.height = this.saveDATA.length * this.itemHeight + "px"; // 新創建的盒子divWarpChild let divWarpChild = document.createElement("div"); divWarpChild.className = "fix-warp divWarpChild"; // 把tableRef的第一個子元素移動到新創建的盒子divWarpChild中 divWarpChild.append(this.tableRef.children[0]); // 把divWarpChild添加到divWarpPar中,最把divWarpPar添加到tableRef中 divWarpPar.append(divWarpChild); this.tableRef.append(divWarpPar); } // left改造 let dlp = box.getElementsByClassName("divLeftPar")[0]; if (dlp) { dlp.style.height = this.saveDATA.length * this.itemHeight + "px"; } else { let divLeftPar = document.createElement("div"); divLeftPar.className = "divLeftPar"; divLeftPar.style.height = this.saveDATA.length * this.itemHeight + "px"; let divLeftChild = document.createElement("div"); divLeftChild.className = "fix-left"; this.tableFixedLeft && divLeftChild.append(this.tableFixedLeft.children[0]); divLeftPar.append(divLeftChild); this.tableFixedLeft && this.tableFixedLeft.append(divLeftPar); } // right改造 let drp = box.getElementsByClassName("divRightPar")[0]; if (drp) { drp.style.height = this.saveDATA.length * this.itemHeight + "px"; } else { let divRightPar = document.createElement("div"); divRightPar.className = "divRightPar"; divRightPar.style.height = this.saveDATA.length * this.itemHeight + "px"; let divRightChild = document.createElement("div"); divRightChild.className = "fix-right"; this.tableFixedRight && divRightChild.append(this.tableFixedRight.children[0]); divRightPar.append(divRightChild); this.tableFixedRight && this.tableFixedRight.append(