Avatar
封装el-tooltip、el-popover溢出隐藏,浮层效果
分享
105
4 个月前

el-tooltip

vue 复制代码
<template>
  <el-tooltip
    effect="dark"
    :content="props.tooltipContent ? props.tooltipContent : props.content"
    placement="top"
    :disabled="isShow"
    popper-class="diy-tooltip"
  >
    <template #content>
      <slot name="tooltipContent">{{ props.tooltipContent ? props.tooltipContent : props.content }}</slot>
    </template>
    <div>
      <div
        v-if="!props.multiline"
        class="content"
        :style="{ width: props.width ? props.width : '100%' }"
        @mouseover="isShowTooltip"
      >
        <span ref="contentRef">
          <!-- 给一个没有写插槽的默认值,兼容纯文本的情况 -->
          <slot name="content">{{ props.content }}</slot>
        </span>
      </div>
      <div v-else class="content2" :style="{ width: props.width ? props.width : '100%' }" @mouseover="isShowTooltip2">
        <span ref="contentRef">
          <!-- 给一个没有写插槽的默认值,兼容纯文本的情况 -->
          <slot name="content">{{ props.content }}</slot>
        </span>
      </div>
    </div>
  </el-tooltip>
</template>
<script setup lang="ts">
import { ref } from "vue"

interface props {
  content?: string
  width?: string
  tooltipContent?: string
  multiline?: boolean
}
const props = withDefaults(defineProps<props>(), {
  content: "",
  width: null,
  tooltipContent: "",
  multiline: false
})
// 使用isShow来控制tooltip是否显示
let isShow = ref<boolean>(true)
// 在span标签上定义一个ref
const contentRef = ref()
const isShowTooltip = function (): void {
  // 计算span标签的offsetWidth与盒子元素的offsetWidth,给isShow赋值
  if (props.multiline) {
    isShow.value = false
  } else {
    if (contentRef.value.parentNode.offsetWidth > contentRef.value.offsetWidth) {
      isShow.value = true
    } else {
      isShow.value = false
    }
  }
}
const isShowTooltip2 = () => {
  if (contentRef.value.offsetHeight > contentRef.value.parentNode.offsetHeight) {
    isShow.value = false
  } else {
    isShow.value = true
  }
}
</script>
<style>
.content {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.content2 {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  display: -webkit-line-clamp;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.diy-tooltip {
  max-width: 500px;
}
</style>

el-popover

vue 复制代码
<template>
  <div ref="container" class="tags-container" @mouseover="isShowPopover">
    <el-popover placement="bottom-start" width="500" :disabled="isShow">
      <template #reference>
        <div class="tag-item" ref="tagItem">
          <el-tag v-for="(tag, index) in tags" :key="index" style="margin-right: 5px">
            {{ tag }}
          </el-tag>
        </div>
      </template>
      <div>
        <el-tag v-for="(tag, index) in tags" :key="index" style="margin: 2px">
          {{ tag }}
        </el-tag>
      </div>
    </el-popover>
  </div>
</template>

<script setup>
import { ref } from "vue"
const props = defineProps({
  tags: {
    type: Array,
    default: () => []
  }
})

const container = ref(null)
const tagItem = ref(null)
const isShow = ref(false)

const isShowPopover = () => {
  const containerWidth = container.value.offsetWidth
  const contentWidth = tagItem.value.offsetWidth
  if (contentWidth == containerWidth) {
    isShow.value = false
  } else {
    isShow.value = true
  }
}
</script>

<style scoped>
.tags-container {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
}

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

.ellipsis {
  cursor: pointer;
  white-space: nowrap;
}
</style>