vue3自定义指令丝滑的解决el-table展示多行的tooltip

目的是为了当el-table的一个单元格展示多行的内容,又使用了文字的省略,需要区分出文字不多不被省略的单元格不展示tooltip,文字很多被省略的展示tooltip

原理是使用自定义指令

首先创建类,用于文字的省略,超出的文字会以……的形式展示

.text-ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

在el-table中使用自定义指令v-hiddeTooltip,原理是使用el-tooltip包裹单元格,不要使用show-overflow-tooltip,通过el-tooltip的插槽展示多行的内容,通过自定义指令判断什么情况下禁用el-tooltip

<el-table-column label="信息很多" prop="points" min-width="170">
        <template #default="{ row }">
          <el-tooltip :disabled="!row.hiddeTooltip" placement="top">
            <template #content>
              <div class="column-left">
                <span>世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
                <span>世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
                <span>世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
              </div>
            </template>
            <div v-hiddeTooltip="row" class="column-left">
              <span class="text-ellipsis">世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
              <span class="text-ellipsis">世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
              <span class="text-ellipsis">世有伯乐,然后有千里马。世有伯乐,然后有千里马。</span>
            </div>
          </el-tooltip>
        </template>
      </el-table-column>

自定义指令v-hiddeTooltip的内容为

import type { App } from 'vue'
// 来自element源码
const getPadding = (el: HTMLElement) => {
  const style = window.getComputedStyle(el, null)
  const paddingLeft = Number.parseInt(style.paddingLeft, 10) || 0
  const paddingRight = Number.parseInt(style.paddingRight, 10) || 0
  const paddingTop = Number.parseInt(style.paddingTop, 10) || 0
  const paddingBottom = Number.parseInt(style.paddingBottom, 10) || 0
  return {
    left: paddingLeft,
    right: paddingRight,
    top: paddingTop,
    bottom: paddingBottom
  }
}
export function hiddeTooltip(app: App) {
  app.directive('hiddeTooltip', {
    mounted(el, binding) {
      const list = el.querySelectorAll('.text-ellipsis') as Array<HTMLElement>
      let flag = false
      for (let index = 0; index < list.length; index++) {
        const cellChild = list[index]
        // 来自element源码
        const range = document.createRange()
        range.setStart(cellChild, 0)
        range.setEnd(cellChild, cellChild.childNodes.length)
        let rangeWidth = range.getBoundingClientRect().width
        let rangeHeight = range.getBoundingClientRect().height
        const offsetWidth = rangeWidth - Math.floor(rangeWidth)
        if (offsetWidth < 0.001) {
          rangeWidth = Math.floor(rangeWidth)
        }
        const offsetHeight = rangeHeight - Math.floor(rangeHeight)
        if (offsetHeight < 0.001) {
          rangeHeight = Math.floor(rangeHeight)
        }

        const { top, left, right, bottom } = getPadding(cellChild)
        const horizontalPadding = left + right
        const verticalPadding = top + bottom
        // 判断也是来自源码
        if (
          rangeWidth + horizontalPadding > cellChild.offsetWidth ||
          rangeHeight + verticalPadding > cellChild.offsetHeight ||
          cellChild.scrollWidth > cellChild.offsetWidth
        ) {
          flag = true
        }
      }
      // 只要最后是个true
      if (flag) {
        binding.value.hiddeTooltip = true
      }
    }
  })
}

自定义指令代码的原理是,验证自定义指令绑定的单元格下的每一个的有text-ellipsis的元素是否符合已经被省略的条件,只要有一个被省略的,flag即为true,反哺出去,把表格中绑定位置的单元格位置的hiddeTooltip属性赋值为true,之后通过hiddeTooltip属性去判断外部包围的el-tooltiip是否Disabled禁用。

是否符合已经被省略的条件的源码来自element-plus的源码,可以下载源码,直接搜索  // 判断是否text-overflow, 如果是就显示tooltip  找到events-helper.ts就能看到源码了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值