diff --git a/package-lock.json b/package-lock.json index a97fcfd..40ea8d7 100755 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,10 @@ "axios": "^1.8.3", "core-js": "^3.40.0", "element-ui": "^2.15.14", + "lodash-es": "^4.17.21", "lottie-web": "^5.12.2", "regenerator-runtime": "^0.14.1", + "resize-observer-polyfill": "^1.5.1", "vue": "^2.6.14", "vue-clickaway": "^2.2.2", "vue-router": "^3.5.1", @@ -7568,6 +7570,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9695,8 +9703,9 @@ }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", - "resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.10", diff --git a/package.json b/package.json index b0f119b..08b9e20 100755 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "axios": "^1.8.3", "core-js": "^3.40.0", "element-ui": "^2.15.14", + "lodash-es": "^4.17.21", "lottie-web": "^5.12.2", "regenerator-runtime": "^0.14.1", + "resize-observer-polyfill": "^1.5.1", "vue": "^2.6.14", "vue-clickaway": "^2.2.2", "vue-router": "^3.5.1", diff --git a/src/mixins/tableResizeMixin.js b/src/mixins/tableResizeMixin.js new file mode 100644 index 0000000..5634b3b --- /dev/null +++ b/src/mixins/tableResizeMixin.js @@ -0,0 +1,228 @@ +import ResizeObserver from 'resize-observer-polyfill'; +import { + debounce +} from 'lodash-es'; + +export default { + data() { + return { + tableResizeObserver: null, + tableWidth: 0 + }; + }, + + methods: { + // 初始化表格宽度监听 + initTableResizeObserver(tableRef, containerRef) { + this.$nextTick(() => { + const container = containerRef ? this.$refs[containerRef] : this.$el; + if (!container) { + console.warn('Table container not found'); + return; + } + + // 先断开已有观察者 + this.destroyTableResizeObserver(); + + this.tableResizeObserver = new ResizeObserver( + debounce(entries => { + const entry = entries[0]; + const newWidth = entry.contentRect.width; + + if (Math.abs(newWidth - this.tableWidth) > 5) { + this.tableWidth = newWidth; + this.syncTableColumns(tableRef); + } + }, 100) + ); + + try { + this.tableResizeObserver.observe(container); + } catch (err) { + console.error('Failed to observe table:', err); + } + }); + }, + + // 同步表头和表体列宽 + syncTableColumns(tableRef) { + // const table = this.$refs[tableRef]; + const table = this.$refs[tableRef].$refs.guiptable; + // console.log(table, 'table====--'); + if (!table) return; + let columns = table.columns; + // console.log(table,table['columns'],table.bodyWidth,'table.columns==='); + // 计算各列宽度(由具体组件实现) + const columnWidths = this.calculateColumnWidths(); + if (!columnWidths) return; + // console.log(columnWidths, 'table.columns==='); + // 设置列宽并同步表头表体 + this.$nextTick(() => { + // 设置列定义中的宽度 + columns.forEach(column => { + // console.log(column.property,'columns====columns'); + if (columnWidths[column.property]) { + column.width = columnWidths[column.property]; + } + }); + + // 同步DOM元素的宽度 + // const headerCols = table.$el.querySelectorAll('.el-table__header col'); + // const bodyCols = table.$el.querySelectorAll('.el-table__body col'); + + // columns.forEach((column, index) => { + // if (columnWidths[column.property] && headerCols[index] && bodyCols[index]) { + // const width = columnWidths[column.property]; + // headerCols[index].width = width; + // headerCols[index].style.setProperty('width',`${width}px`, 'important'); + // // headerCols[index].style.width = `${width}px`; + // bodyCols[index].width = width; + // bodyCols[index].style.setProperty('width',`${width}px`, 'important'); + // // bodyCols[index].style.width = `${width}px`; + // } + // }); + + // 强制表格重新布局 + table.doLayout(); + // this.syncFixedColumns(table); + this.$nextTick(() => { + // 3. 同步主表格 + this.syncColumns( + table.$el, + columnWidths, + table.columns + ); + + // 4. 同步固定列 + const fixedLeft = table.$el.querySelector('.el-table__fixed'); + const fixedRight = table.$el.querySelector('.el-table__fixed-right'); + + if (fixedLeft) this.syncColumns(fixedLeft, columnWidths, table.columns); + if (fixedRight) this.syncColumns(fixedRight, columnWidths, table.columns); + + // 5. 强制布局更新(需要两次nextTick确保固定列更新) + this.$nextTick(() => { + table.doLayout(); + setTimeout(() => table.doLayout(), 50); + }); + }); + + }); + }, + syncColumns(container, columnWidths, columns) { + const headerCols = container.querySelectorAll('.el-table__header col, [class*=-header-wrapper] col'); + const bodyCols = container.querySelectorAll('.el-table__body col, [class*=-body-wrapper] col'); + + columns.forEach((column, index) => { + const width = columnWidths[column.property]; + if (width && headerCols[index] && bodyCols[index]) { + headerCols[index].width = width; + // headerCols[index].style.width = `${width}px`; + headerCols[index].style.setProperty('width',`${width}px`, 'important'); + + bodyCols[index].width = width; + // bodyCols[index].style.width = `${width}px`; + bodyCols[index].style.setProperty('width',`${width}px`, 'important'); + + } + }); + }, + // syncTableColumns(tableRef) { + // const table = this.$refs[tableRef].$refs.guiptable; + // if (!table) return; + + // // 计算各列宽度 + // const columnWidths = this.calculateColumnWidths(); + // if (!columnWidths) return; + + // this.$nextTick(() => { + // // 1. 设置列定义的宽度 + // table.columns.forEach(column => { + // if (columnWidths[column.property]) { + // column.width = columnWidths[column.property]; + // column.realWidth = columnWidths[column.property]; // 关键:设置realWidth + // } + // }); + + // // 2. 同步DOM元素的宽度 + // const headerCols = table.$el.querySelectorAll('.el-table__header col'); + // const bodyCols = table.$el.querySelectorAll('.el-table__body col'); + // const headerCells = table.$el.querySelectorAll('.el-table__header .cell'); + // // const bodyCells = table.$el.querySelectorAll('.el-table__body .cell'); + + // table.columns.forEach((column, index) => { + // if (columnWidths[column.property]) { + // const width = columnWidths[column.property]; + + // // 同步colgroup中的宽度 + // if (headerCols[index]) { + // headerCols[index].width = width; + // headerCols[index].style.width = `${width}px`; + // } + // if (bodyCols[index]) { + // bodyCols[index].width = width; + // bodyCols[index].style.width = `${width}px`; + // } + + // // 同步单元格的实际宽度 + // if (headerCells[index]) { + // headerCells[index].style.width = `${width}px`; + // } + // // body单元格通常不需要强制设置宽度 + // } + // }); + + // // 3. 强制更新布局 + // table.store.scheduleLayout(); + + // // 4. 处理固定列 + // this.syncFixedColumns(table); + // }); + // }, + + // syncFixedColumns(table) { + // // 处理左侧固定列 + // const fixedLeftWrapper = table.$el.querySelector('.el-table__fixed'); + // if (fixedLeftWrapper) { + // const fixedLeftCols = fixedLeftWrapper.querySelectorAll('col'); + // const originalCols = table.$el.querySelectorAll('.el-table__header col'); + + // fixedLeftCols.forEach((col, index) => { + // if (originalCols[index]) { + // const width = originalCols[index].width; + // col.width = width; + // // col.style.width = `${width}px`; + // col.style.setProperty('width',`${width}px`, 'important'); + + // } + // }); + + // // 强制重绘固定列 + // fixedLeftWrapper.style.display = 'none'; + // this.$nextTick(() => { + // fixedLeftWrapper.style.display = ''; + // }); + // } + + // // 同样处理右侧固定列... + // }, + + + // 销毁观察者 + destroyTableResizeObserver() { + if (this.tableResizeObserver) { + this.tableResizeObserver.disconnect(); + this.tableResizeObserver = null; + } + }, + + // 需要组件自己实现的计算列宽方法 + calculateColumnWidths() { + throw new Error('Component must implement calculateColumnWidths method'); + } + }, + + beforeDestroy() { + this.destroyTableResizeObserver(); + } +}; \ No newline at end of file diff --git a/src/views/elementGroups.vue b/src/views/elementGroups.vue index 10c8746..5d7af78 100644 --- a/src/views/elementGroups.vue +++ b/src/views/elementGroups.vue @@ -28,10 +28,10 @@ defaultValue="全部检测类型" @change="changeSelectType" /> - --> - - + +