实现一个ellipsis组件

476 阅读2分钟

实现一个ellipsis组件

大家好,我是铁柱,时常分享一些项目的收获。 点赞 + 关注 + 收藏 = 学会了

背景

最近有这么个需求,需要实现文本超出显示省略号,并且鼠标放上去显示全部内容,不超出的则正常显示,还需支持动态数据,于是就想着自己实现一个这样子的组件,下面就开始开动。

基础知识点

主要就是比较 scrollWidthclientWidth 这两者的关系判断是否显示省略号,使用html自带的 title 属性显示全部内容

  • 每一个 DOM 节点都有 scrollWidth 属性,这个只读属性表示的是节点中的内容宽度,包括由于overflow溢出而在屏幕上不可见的内容。 scrollWidth 值等于元素在不使用水平滚动条的情况下在视口中展示所有内容时所需的最小宽度。其测量方式与 clientWidth 相同:它包含元素的内边距(padding-left 和 padding-right),但不包括边框(border)、外边距(margin-left 和 margin-right)和垂直滚动条(如果存在)。 它还可以包括伪元素的宽度,例如::before或::after。 如果元素的内容不需要水平滚动就可以完全展示出来,则其 scrollWidth 等于 clientWidth

  • scrollWidth属性会进行四舍五入并返回整数,如果你需要小数形式的值可以使用element.getBoundingClientRect()

  • 所有浏览器都支持 scrollWidth 属性,但是在不同浏览器中获取到的值不相同。在实际测试过程中,谷歌获取的 Element.scrollWidth 和 IE、火狐下获取的 Element.scrollWidth 不相同。

  • 这个组件暂时不考虑 scrollWidth 可能会带来的一些bug,如果需要考虑可以使用 Rang 代替 scrollWidth

自定义ellipsis组件

了解基础知识之后那就实现一个与业务无关并且脱离于其他组件的 ellipsis 组件。使用html自带的 title 属性实现鼠标放上去显示全部内容,当然有的小伙伴觉得这个属性的显示效果有点low,也可以使用各大组件库的Tooltip组件,具体代码如下

<template>
  <div :id="id" class="my-ellipsis overflow-ellipsis" :title="cTitle" :style="{ maxWidth }">
    <slot>{{ content }}</slot>
  </div>
</template>

<script>
export default {
  name: 'MyEllipsis',
  props: {
    content: {
      type: String | Number,
      required: true,
    },
    title: String | Number,
    maxWidth: {
      type: String,
      default: '90px',
    },
  },
  data() {
    return {
      id: 'my-ellipsis-' + new Date().getTime(),
      dTitle: '',
    }
  },
  computed: {
    // 支持传入title
    cTitle() {
      return this.title || this.dTitle
    },
  },
  watch: {
    // 写在watch中的原因,当绑定的内容变化时视图也可以实时更新
    content: {
      handler() {
        this.$nextTick(() => {
          if (!this.title) {
            const el = document.getElementById(this.id)
            if (el.scrollWidth !== el.clientWidth) {
              this.dTitle = this.content
            }
          }
        })
      },
      immediate: true,
    },
  },
}
</script>

<style scoped lang="less">
.overflow-ellipsis {
  display: inline-block;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1;
}
</style>