基于element-ui实现的Tooltip 文字提示效果

95 阅读1分钟

textElpise.vue

<template>
  <el-popover
    :placement="placement"
    :disabled="!isShowToolTip"
    :trigger="trigger"
  >
    <p
      ref="text"
      slot="reference"
      :class="[row === 1 ? 'single' : 'multiline']"
      :style="`-webkit-line-clamp: ${row === 1 ? 'none' : row}`"
      v-html="text"
    ></p>
    <p v-html="text" :style="`text-align: ${align}; max-width: ${maxW}px`"></p>
  </el-popover>
</template>

<script>
import ResizeObserver from 'resize-observer-polyfill'

export default {
  props: {
    text: { type: String, default: '' },
    placement: { type: String, default: 'top-start' },
    trigger: { type: String, default: 'hover' },
    align: { type: String, default: 'left' },
    row: { type: [Number, String], default: 1 }, // 行数
    maxW: { type: [Number, String], default: 400 },
    resize: { type: Boolean, default: true }, // 是否开启resize监听
  },
  data() {
    return { isShowToolTip: false, ro: null }
  },
  methods: {
    // 省略判断
    determine() {
      const node = this.$refs.text || null
      if (!node) return
      this.isShowToopTip =
        this.row === 1
          ? node.clientWidth < node.scrollWidth // 单行
          : node.clientHeight < node.scrollHeight // 多行
    },
    // 开启resize监听
    monitor() {
      if (this.resize) {
        this.ro = new ResizeObserver(_.debounce(this.determine, 500))
        this.ro.observe(this.$refs.text)
      } else {
        this.determine()
      }
    },
  },
  mounted() {
    this.isShowToolTip = true
    this.ro = null
    this.monitor()
  },
  beforeDestroy() {
    if (!this.resize || !this.ro || !this.$refs.text) return
    this.ro.unobserve(this.$refs.text)
  },
}
</script>

<style lang="scss" scoped>
.single {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
.multiline {
  word-break: break-all;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}
</style>

demo.vue

<template>
  <div>
    <div style="width: 500px">
      <TextElpise
        :text="text"
        :placement="'top-start'"
        :trigger="'hover'"
        :row="3"
        :resize="true"
      ></TextElpise>
    </div>
  </div>
</template>

<script>
import TextElpise from '@/components/textElpise.vue'

export default {
  components: {
    TextElpise,
  },
  data() {
    return {
      text: '文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字123',
    }
  },
}
</script>

image.png

转载至:juejin.cn/post/725445…