From c4ca28d2d9fded9dd887b86ab170b5f2d8218ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chuailei000=E2=80=9D?= <2280131253@qq.com> Date: Wed, 25 Oct 2023 14:51:41 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96table=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=86=85=E5=AE=B9=E6=BA=A2=E5=87=BA=E7=9C=81=E7=95=A5?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E9=BC=A0=E6=A0=87=E5=8F=AF=E4=BB=A5=E7=A7=BB?= =?UTF-8?q?=E5=85=A5tooltip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 3 + src/styles/index.scss | 1 + src/utils/elTableTooltipPatch.js | 113 +++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 src/utils/elTableTooltipPatch.js diff --git a/src/main.js b/src/main.js index 652198e45..537ce610a 100644 --- a/src/main.js +++ b/src/main.js @@ -22,6 +22,7 @@ import ECharts from 'vue-echarts' import service from '@/utils/request' import { message } from '@/utils/message' import xss from '@/utils/xss' +import ElTableTooltipPatch from '@/utils/elTableTooltipPatch.js' /** * If you don't want to use mock-server @@ -41,6 +42,8 @@ Vue.use(ElementUI, { locale }) // 如果想要中文版 element-ui,按如下方式声明 // Vue.use(ElementUI) +Vue.use(ElTableTooltipPatch) + Vue.config.productionTip = false Vue.use(VueCookie) diff --git a/src/styles/index.scss b/src/styles/index.scss index 5b1d60598..bcece4dfd 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -24,6 +24,7 @@ body { height: calc(100% - 50px); + overflow: hidden; -moz-osx-font-smoothing: grayscale; color: #676a6c; font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; diff --git a/src/utils/elTableTooltipPatch.js b/src/utils/elTableTooltipPatch.js new file mode 100644 index 000000000..18e045a49 --- /dev/null +++ b/src/utils/elTableTooltipPatch.js @@ -0,0 +1,113 @@ +// 鼠标可移入tooltip功能 +import { Table } from 'element-ui' +import { getCell, getColumnByCell } from 'element-ui/packages/table/src/util' +import { getStyle, hasClass } from 'element-ui/src/utils/dom' +import i18n from '@/i18n/i18n' +import { message } from './message' + +Object.assign(Table.components.TableBody.methods, { + handleCellMouseEnter(event, row) { + const { table } = this + const cell = getCell(event) + + if (cell) { + const column = getColumnByCell(table, cell) + table.hoverState = { cell, column, row } + const { hoverState } = table + table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event) + } + + // 判断是否text-overflow, 如果是就显示tooltip + const cellChild = event.target.querySelector('.cell') + if (!(hasClass(cellChild, 'el-tooltip') && cellChild.childNodes.length)) { + return + } + // use range width instead of scrollWidth to determine whether the text is overflowing + // to address a potential FireFox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1074543#c3 + const range = document.createRange() + range.setStart(cellChild, 0) + range.setEnd(cellChild, cellChild.childNodes.length) + const rangeWidth = range.getBoundingClientRect().width + const padding = (parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) + + (parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0) + if ( + (rangeWidth + padding > cellChild.offsetWidth || + cellChild.scrollWidth > cellChild.offsetWidth) && + this.$refs.tooltip + ) { + const { tooltip } = this.$refs + const { tooltipEnterable } = this.table + const showTooltip = () => { + this.tooltipContent = cell.innerText || cell.textContent + tooltip.referenceElm = cell + tooltip.doDestroy() + tooltip.setExpectedState(true) + this.activateTooltip(tooltip) + // 点击复制 + tooltip.$refs.popper.onclick = () => { + message.success(i18n.t('common.CopySuccess')) + } + } + if (tooltipEnterable && tooltip.showPopper) { + clearTimeout(tooltip.timeoutEnter) + tooltip.timeoutEnter = setTimeout(() => { + if (!tooltip.expectedState) { + tooltip.handleClosePopper() + } + tooltip.timeoutEnter = null + }, 100) + return + } + if (!tooltipEnterable && tooltip.$refs.popper) { + tooltip.$refs.popper.style.display = 'none' + } + showTooltip() + } + }, + handleCellMouseLeave(event) { + const { tooltip } = this.$refs + if (tooltip) { + tooltip.setExpectedState(false) + const { tooltipEnterable } = this.table + if (tooltipEnterable) { + clearTimeout(tooltip.timeoutLeave) + tooltip.timeoutLeave = setTimeout(() => { + if (!tooltip.expectedState) { + tooltip.handleClosePopper() + } + tooltip.timeoutLeave = null + }, 100) + } else { + tooltip.handleClosePopper() + } + } + const cell = getCell(event) + if (!cell) return + + const oldHoverState = this.table.hoverState || {} + this.table.$emit( + 'cell-mouse-leave', + oldHoverState.row, + oldHoverState.column, + oldHoverState.cell, + event, + ) + } +}) + +/** + * @description 扩展el-table,实现当showOverflowTooltip时,鼠标可移入tooltip功能 + * @prop {Boolean} tooltipEnterable 仅在列属性showOverflowTooltip为true时生效,鼠标是否可进入到 tooltip 中,默认为true +*/ +const ElTable = { + extends: Table, + props: { + tooltipEnterable: { + type: Boolean, + default: true + } + } +} +export default (Vue) => { + Vue.component('ElTable', ElTable) +}