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>