赞
踩
- <!-- vp-tooltip.vue -->
- <template>
- <div
- class="vp-tooltip"
- @mouseenter="handleCellMouseEnter"
- @mouseleave="handleCellMouseLeave"
- >
- <div :class="classObj" :style="styleObj">
- <slot></slot>
- </div>
- <el-tooltip ref="tooltip" placement="top" :content="tooltipContent">
- <template v-if="$slots.content" #content>
- <slot name="content"></slot>
- </template>
- </el-tooltip>
- </div>
- </template>
-
- <script>
- import debounce from "throttle-debounce/debounce";
- import { getStyle, hasClass } from "element-ui/src/utils/dom";
-
- /**
- * 显隐可控的tooltip组件
- * @desc 基于element-ui抽离,组件内部自动计算文本是否超宽来决定tooltip调用与否
- */
- export default {
- name: "VpTooltip",
- componentName: "VpTooltip",
- props: {
- // 限定超宽范围
- width: {
- String,
- default: "180px",
- },
- // tooltip显示的内容
- content: String,
- // cell自定义样式
- cellStyle: {
- type: Object,
- default: () => ({}),
- },
- // 保留属性,意义不大,纯粹为了与源码结构保持一致
- showOverflowTooltip: {
- type: Boolean,
- default: true,
- },
- },
- data() {
- return {
- tooltipContent: "",
- };
- },
- computed: {
- classObj() {
- return {
- cell: true,
- "el-tooltip": this.showOverflowTooltip,
- };
- },
- styleObj() {
- return {
- ...this.cellStyle,
- width: this.width,
- };
- },
- },
- created() {
- // 防抖函数保护,避免鼠标键入后n秒内多次调用
- this.activateTooltip = debounce(50, (tooltip) =>
- tooltip.handleShowPopper()
- );
- },
- methods: {
- // 鼠标键入显示tooltip
- handleCellMouseEnter(event) {
- // 无提示内容直接返回
- if (!this.content && !this.$slots.content) {
- return;
- }
- const cell = event.target;
- // 判断是否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, 1);
- const rangeWidth = range.getBoundingClientRect().width;
- const padding =
- (parseInt(getStyle(cellChild, "paddingLeft"), 10) || 0) +
- (parseInt(getStyle(cellChild, "paddingRight"), 10) || 0);
- // 判断文本 + padding的宽度是否超过容器宽度
- if (
- (rangeWidth + padding > cellChild.offsetWidth ||
- cellChild.scrollWidth > cellChild.offsetWidth) &&
- this.$refs.tooltip
- ) {
- const tooltip = this.$refs.tooltip;
- // TODO 会引起整个 Table 的重新渲染,需要优化
- this.tooltipContent = this.content; // 这里为啥写这行类似1=1的代码呢,纯粹为了与源码结构保持一致
- tooltip.referenceElm = cell;
- tooltip.$refs.popper && (tooltip.$refs.popper.style.display = "none");
- tooltip.doDestroy();
- tooltip.setExpectedState(true);
- this.activateTooltip(tooltip);
- }
- },
- // 鼠标移出关闭tooltip
- handleCellMouseLeave() {
- const tooltip = this.$refs.tooltip;
- if (tooltip) {
- tooltip.setExpectedState(false);
- tooltip.handleClosePopper();
- }
- },
- },
- };
- </script>
-
- <style scoped>
- .vp-tooltip .cell {
- box-sizing: border-box;
- word-break: break-all;
- /* padding-left: 10px; */
- padding-right: 10px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- </style>
使用的时候
import Vptip from "@/components/vptip" // 自定义Tooltip 文字提示
- <Vptip :content="item.templateFieldName" :width="'100%'" style="max-width: 500px;" class="item">
- {{ `${item.templateFieldName}` }}
- </Vptip>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。