SOURCE

<template>
  <template v-if="isTooltip">
    <el-tooltip ref="tooltipRef" v-bind="getProps" :popper-class="`base-tooltip ${popperClass}`">
      <template #content>
        <div class="base-tooltip-content">
          <slot name="content">{{ content || text }}</slot>
        </div>
      </template>
      <template v-if="auto" #default>
        <div class="is-auto-tips" :style="getStyle" ref="contentRef">
          <slot></slot>
        </div>
      </template>
      <template v-else #default>
        <slot></slot>
      </template>
    </el-tooltip>
  </template>
  <template v-if="!isTooltip && auto">
    <div class="is-auto-tips" :style="getStyle" ref="contentRef" @mouseenter="setIsTooltip">
      <slot></slot>
    </div>
  </template>
</template>

<script setup>
import { ElTooltip } from 'element-plus'
import { toRefs, ref, computed, nextTick, onMounted, onBeforeUnmount } from 'vue'
defineOptions({
  name: 'BaseToolTip',
  inheritAttrs: false,
})
const props = defineProps({
  ...ElTooltip.props,
  // 是否自动计算显示tips
  auto: {
    type: Boolean,
    default: true,
  },
  // 最大显示行数
  rows: {
    type: Number,
    default: 100,
  },
})

const emits = defineEmits([...ElTooltip.emits])

const { auto, rows, popperClass, content } = toRefs(props)
// 是否渲染为tooltip模式
const isTooltip = ref(!auto.value)
const contentRef = ref(null)
const text = ref('')
const tooltipRef = ref(null)

const getProps = computed(() => {
  return props
})

const getStyle = computed(() => {
  return {
    '-webkit-line-clamp': rows.value,
  }
})

const updateIsTooltip = () => {
  text.value = contentRef.value.innerText
  isTooltip.value = !!(contentRef.value?.scrollHeight - contentRef.value?.offsetHeight > 1)
}

const setIsTooltip = async () => {
  // 自动计算状态下判断高度显示是否溢出,则显示为tooltip模式
  if (auto.value && !isTooltip.value) {
    await nextTick()
    updateIsTooltip()
  }
}

const observer = ref(null)

onMounted(() => {
  if (contentRef.value) {
    observer.value = new MutationObserver(setIsTooltip)
    observer.value.observe(contentRef.value, {
      childList: true,
      subtree: true,
    })
  }
})

onBeforeUnmount(() => {
  if (observer.value) {
    observer.value.disconnect()
  }
})

defineExpose({ tooltipRef })
</script>

<style lang="scss">
.is-auto-tips {
  word-break: break-all;
  white-space: normal;
  font-style: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}

.base-tooltip {
  max-width: 300px;
  line-height: 24px;
  word-break: break-all;
}
</style>
console 命令行工具 X clear

                    
>
console