SOURCE

<template>
  <template v-if="isTooltip">
    <el-tooltip ref="tooltipRef" :visible="false" 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" @mouseenter="setIsTooltip">
          <slot>{{ content || text }}</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>{{ content || text }}</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: Infinity
  }
});

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) {
    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