Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Vue

  • ElementUI

    • 基于 ElementUI 封装的 TextEllipsis
      • 封装思路:
      • 代码
      • 扩展 - 多行
      • 问题
        • padding 会有影响
    • 基于 ElementUI 封装的 Tree
    • 基于 ElementUI 封装的 Tree2
    • 基于 ElementUI 封装的 SelectTree
    • 基于 ElementUI 封装的 NumberInput
    • 基于 ElementUI 封装的基础 table 和 form
    • 基于 ElementUI 封装的 TreeTable
    • 基于 VuePress 搭建一个类似 ElementUI 的说明文档
    • el-tree 节点过滤加载对应子节点
    • 简单调试 node_modules 源码
    • ElementUI 问题集合
    • 树形表格更新后保持折叠状态
    • 开始和完成时间互相限制
  • React

  • AntD

  • 前端
  • ElementUI
Henry
2020-09-03
目录

基于 ElementUI 封装的 TextEllipsis

做项目中文本溢出显示省略号是一个非常常见的功能, 一般做法都是增加 css 样式并且鼠标悬浮后显示全部内容, 但有时候明明没有溢出, 悬浮也会显示内容, 所以我们需要做一点处理

这里是源码 (opens new window)

这里我们主要使用 el-tooltip 这个组件来实现这个功能

# 封装思路:

  1. 通过 content 传入文本
  2. 通过 css 实现溢出显示省略号的样式
  3. 鼠标悬浮后, 判断 scrollWidth 是否超过 offsetWidth, 如果超过, 显示 tooltip, 否则设置 disabled

由于比较简单, 直接上代码了:

# 代码

<template>
  <el-tooltip class="text-ellipsis" v-bind="$attrs" :disabled="disabled" :content="content">
    <div @mouseenter.stop="handleMouseEnter">
      {{ content }}
    </div>
  </el-tooltip>
</template>

<script>
  export default {
    name: 'TextEllipsis',
    props: {
      content: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        disabled: true
      }
    },
    methods: {
      handleMouseEnter(e) {
        const { scrollWidth, offsetWidth } = e.target
        this.disabled = scrollWidth <= offsetWidth
      }
    }
  }
</script>

<style lang="less" scoped>
  .text-ellipsis {
    width: 100%;
    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

# 扩展 - 多行

最近遇到需要多行溢出显示省略号的需求, 而咱们这个只支持单行, 所以需要扩展一下

css 样式比较好搞定:

.text-ellipsis {
  width: 100%;
  overflow: hidden;
  display: -webkit-box;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
}
1
2
3
4
5
6
7

-webkit-line-clamp 这个属性需要通过 props 接收并在 div 中设置:

<div :style="{ '-webkit-line-clamp': lineClamp }" @mouseenter.stop="handleMouseEnter">
  {{ content }}
</div>
1
2
3

而 js 就比较麻烦了, 在群里问了大佬一下, 貌似没有哪个方法可以获取是否出现省略号, 都需要自己计算来获取

而且都比较麻烦, 需要判断 padding border 等尺寸, 而咱们一般使用比较简单, 没那么复杂, 所以就参照以前的改改吧

此时就需要用 height 来代替 width 计算是否出现省略号:

handleMouseEnter({ target }) {
  const { scrollHeight, offsetHeight } = target
  this.disabled = scrollHeight <= offsetHeight
}
1
2
3
4

本来测试的是没问题的, 没想到项目实际中竟然出现 scrollHeight 比 offsetHeight 多 1px 的情况, 导致明明没有出现省略号, 鼠标悬浮上去的时候会显示 tooltip

经过一番研究后发现如果出现省略号, 那么 scrollHeight 的高度至少比 offsetHeight 高一行, 那么能不能按照这个逻辑来计算呢?

handleMouseEnter({ target }) {
  const { scrollHeight, offsetHeight } = target
  // 这里不能再用 <=
  this.disabled = scrollHeight - offsetHeight < offsetHeight / this.lineClamp
}
1
2
3
4
5

再次测试后, 发现如果增加 border, scrollHeight 的高度比 offsetHeight 高一行时, 计算仍有误, 这是因为 offsetHeight 有 border 的宽度, 而 scrollHeight 并没有, 所以还是用 clientHeight 吧

handleMouseEnter({ target }) {
  const { scrollHeight, clientHeight } = target
  // 这里不能再用 <=
  this.disabled = scrollHeight - clientHeight < clientHeight / this.lineClamp
}
1
2
3
4
5

# 问题

# padding 会有影响

padding

如图所示, 这里设置 padding: 50px, 可以看到虽然出现了省略号, 但第四行并没有被隐藏, 而且计算又有误了, 只有当出现第五行的时候, 计算才正确

这个 bug 目前就不打算解决了, 毕竟 chrome 还没有解决呢! 🐶

其实这个说难很难, 说简单也简单!

在外面包裹一层不就可以了吗? 外层控制位置等样式, 内层控制多行省略号即可

<el-tooltip
  class="text-ellipsis"
  v-bind="$attrs"
  :disabled="disabled"
  :content="content"
  :open-delay="openDelay"
>
  <div>
    <div
      class="text-ellipsis-content"
      :style="{ '-webkit-line-clamp': lineClamp }"
      @mouseenter.stop="handleMouseEnter"
    >
      {{ content }}
    </div>
  </div>
</el-tooltip>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.text-ellipsis {
  width: 100%;
  &-content {
    display: -webkit-box;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal; // 使用默认值, 防止继承属性的时候高度计算有误
    -webkit-box-orient: vertical;
  }
}
1
2
3
4
5
6
7
8
9
10
11
编辑 (opens new window)
#Js#ElementUI
上次更新: 5/27/2023, 1:02:05 PM
vuepress 如何引入 vuex
基于 ElementUI 封装的 Tree

← vuepress 如何引入 vuex 基于 ElementUI 封装的 Tree→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式