Wiidede's blog Wiidede's blog
  • 前端
  • Python
  • 算法
  • 生活
  • 其他
  • 分类
  • 标签
  • 归档
  • 关于我
  • 赞赏
  • 我的小站 (opens new window)
GitHub (opens new window)

Wiidede

小的的写前端
  • 前端
  • Python
  • 算法
  • 生活
  • 其他
  • 分类
  • 标签
  • 归档
  • 关于我
  • 赞赏
  • 我的小站 (opens new window)
GitHub (opens new window)
  • 整理一些css样式
  • vue隔代组件层层动态插槽并且附带数据
  • vue判断字符串是否溢出来显示弹窗、解决el-table tooltip 内过多导致无法显示,内容闪烁
    • vue判断字符串是否溢出来显示弹窗
    • 处理函数 isOverflow
    • 整理成组件(仅判断字符串是否溢出)
    • 解决el-table tooltip 内过多导致无法显示,内容闪烁
      • 改进:正常显示
      • 改进:自动判断鼠标是否需要移入
      • 改进:结构改为div包着span,和原来el-table的样子差不多
    • 最终的组件
    • Vue3 + TS 组件重新封装,支持多行省略
  • 整理一些js写法
  • ElementUI timePicker 增加此刻按钮 引发的dom操作的学习
  • 毕业设计(水表识别)前端知识整理
  • html小知识
  • axios请求api然后下载文件
  • vue3+ts根据高度改变元素的透明度
  • vue3 + ElementPlus 换肤方案(Css变量)
  • Moment的一些使用方法
  • echarts基础vue组件
  • element UI el-date-picker 年月日切换组件
  • 可以不选择的el-radio单选框
  • vue的小技巧总结
  • 全局动态权限判断(Vue指令)
  • vue-anchor 探索
  • Deep Dive with Evan You 笔记
  • 前端基础知识查漏补缺
  • WebPack 知识总结
  • 我写的一些可以日后参考的代码
  • 接口变化后,封装接口函数,改变返回内容
  • 项目组件整理
  • 前端框架设计想发
  • 全局进度条
  • 带有token的图片vue组件:authImg,使用axios下载图片
  • 前端npm包推荐
  • 给ElInputNumber添加prefix
  • ElPagination添加页数总数
  • el-tab做成chrome类似的tab样式
  • vue-grid-layout-组件配置
  • 项目数据字典封装
  • 图表组件响应式探索
  • ElementPlus表格table列自动合并composition
  • 简单的curd组件封装
  • ElementPlus表格自定义合计列composition
  • 一些处理表格数据composition api
  • div内容溢出后,内容向左悬浮,vue组件封装
  • 文本数字溢出后,按比例缩小,vue组件封装
  • 表格使用async-validator检验composition
  • ElementPlus Form一些简单的组件整合
  • arco-design快速使用tailwind的颜色、unocss动态颜色
  • 前端
wiidede
2020-10-15

vue判断字符串是否溢出来显示弹窗、解决el-table tooltip 内过多导致无法显示,内容闪烁

# vue判断字符串是否溢出来显示弹窗、解决el-table tooltip 内过多导致无法显示,内容闪烁

总体的思路就是获取dom元素,根据dom元素的 clientWidth 与 scrollWidth 来判断是否溢出,我这里正好碰到v-for,所以需要动态绑定每一个元素的ref。

# vue判断字符串是否溢出来显示弹窗

<div v-for="item in items" :key="item.id">
    <el-tooltip
                :disabled="isOverflow($refs[item.id])"
                :content="`${item.content}`"
                effect="dark"
                placement="top">
        <span :ref="item.id">{{ item.content }}</span>
    </el-tooltip>
</div>
1
2
3
4
5
6
7
8
9

# 处理函数 isOverflow

const isOverflow = (element) => {
    return element ? element[0].clientWidth >= element[0].scrollWidth : false;
}
1
2
3

# 整理成组件(仅判断字符串是否溢出)

<template>
  <el-tooltip
          :disabled="disabled"
          effect="dark"
          :content="tooltipContent || content"
          placement="top"
          :enterable="false">
    <div ref="overflowTooltipContent"
         :class="className" class="overflow-content" @mouseover="isOverflow">
      {{ content }}
    </div>
  </el-tooltip>
</template>

<script>
export default {
 name: 'overflow-tooltip',
 props: {
  className: {
   type: String,
   default: ''
  },
  content: {
   type: String,
   default: ''
  },
  tooltipContent: {
   type: String,
   default: ''
  }
 },
 data() {
  return {
   disabled: true
  };
 },
 methods: {
  isOverflow() {
   if (this.$refs.overflowTooltipContent) {
    this.disabled = this.$refs.overflowTooltipContent.offsetWidth >= this.$refs.overflowTooltipContent.scrollWidth;
   }
  }
 }
};
</script>

<style lang="scss" scoped>
.overflow-content {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# 解决el-table tooltip 内过多导致无法显示,内容闪烁

# 改进:正常显示

后来在el-table遇到了一个问题,就是el-table原本的tooltip,如果内容太多,是显示不下的,而且屏幕会闪烁,盲猜tooltip出现的瞬间鼠标进入了tooltip,表格的tooltip是无法进入,所以马上消失了,然后又显示。

所以我马上用了这个组件,但是加了一些样式,让它溢出的可以滚动。(如果el-table自带的tooltip用这个样式,也可以正常显示,但是鼠标无法进入,所以无法展示所有内容)

不过加了这个样式好像就不能显示arrow了

.popperClass {
  max-width: 50vw;
  max-height: 50vh;
  overflow-y: auto;
}
1
2
3
4
5

# 改进:自动判断鼠标是否需要移入

鼠标移入后,获取popper节点,判断el-tooltip的内容是否溢出,如果溢出,才允许鼠标进入。

setTimeout(() => {
  const popper = this.$refs.tooltip.$refs.popper;
  if (popper) {
    this.autoEnter = popper.offsetHeight < popper.scrollHeight;
  }
}, 100);
1
2
3
4
5
6

# 改进:结构改为div包着span,和原来el-table的样子差不多

这时候需要修改一下原先判断溢出的方法。

const el = this.$refs.overflowTooltipContent;
if (el) {
  const parent = el.parentNode;
  this.disabled = parent.offsetWidth >= el.offsetWidth;
}
1
2
3
4
5

# 最终的组件

<template>
  <el-tooltip
    ref="tooltip"
    :disabled="disabled"
    effect="dark"
    :content="tooltipContent || content"
    :placement="placement"
    :enterable="autoEnter === null ? enterable : autoEnter"
    :popper-class="popperClass"
    :visible-arrow="false"
  >
    <div class="overflow-content-wrapper">
      <span
        ref="overflowTooltipContent"
        class="overflow-content"
        :class="className"
        @mouseover="isOverflow"
      >{{ content }}</span>
    </div>
  </el-tooltip>
</template>

<script>
export default {
  name: 'OverflowTooltip',
  props: {
    className: {
      type: String,
      default: ''
    },
    content: {
      type: String,
      default: ''
    },
    tooltipContent: {
      type: String,
      default: ''
    },
    enterable: {
      type: Boolean,
      default: false
    },
    autoEnterable: {
      type: Boolean,
      default: false
    },
    popperClass: {
      type: String,
      default: ''
    },
    placement: {
      type: String,
      default: 'top'
    }
  },
  data() {
    return {
      disabled: true,
      autoEnter: null
    };
  },
  methods: {
    isOverflow() {
      const el = this.$refs.overflowTooltipContent;
      if (el) {
        const parent = el.parentNode;
        this.disabled = parent.offsetWidth >= el.offsetWidth;
      }
      if (this.autoEnterable) {
        setTimeout(() => {
          const popper = this.$refs.tooltip.$refs.popper;
          if (popper) {
            this.autoEnter = popper.offsetHeight < popper.scrollHeight;
          }
        }, 100);
      }
    }
  }
};
</script>

<style scoped>
.overflow-content-wrapper {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.overflow-content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

# Vue3 + TS 组件重新封装,支持多行省略

element-plus好像不会出现超多内容闪烁,el-tooltip会自动撑开整个页面,所以这里只是在第一个组件的基础上增加了传入参数就可以支持多行省略。

<template>
  <el-tooltip
    ref="tooltipRef"
    effect="dark"
    :disabled="disabled"
    :content="tooltipContent || content"
  >
    <span
      ref="contentRef"
      class="overflow-content"
      :class="[{'overflow-line-clamp': lineClamp}, className]"
      :style="{'--line-clamp': lineClamp}"
      @mouseover="isOverflow"
    >{{ content }}</span>
  </el-tooltip>
</template>

<script setup lang="ts">
import type { ElTooltip } from 'element-plus/es';

const props = defineProps<{
  content: string;
  className?: string;
  lineClamp?: number;
  tooltipContent?: string;
}>();

const tooltipRef = ref<InstanceType<typeof ElTooltip>>();
const contentRef = ref<HTMLSpanElement>();

const disabled = ref(true);

const isOverflow = () => {
  const el = contentRef.value;
  if (el) {
    if (props.lineClamp) {
      disabled.value = el.offsetHeight >= el.scrollHeight;
    } else {
      disabled.value = el.offsetWidth >= el.scrollWidth;
    }
  }
};
</script>

<style lang="scss" scoped>
.overflow-content {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.overflow-line-clamp {
  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: pre-wrap;
  -webkit-line-clamp: var(--line-clamp, 2);
  -webkit-box-orient: vertical;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#前端#Vue#ElementUI#ElementPlus#Vue组件
上次更新: 2023/06/01, 12:40:50

← vue隔代组件层层动态插槽并且附带数据 整理一些js写法→

Theme by Vdoing | Copyright © 2021-2023 Wiidede | Website use MIT License | Article content & logo use CC-BY-SA-4.0 License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式