vue项目单行文本溢出处理
前言
一般最常见的详情信息展示页面,都需要处理文字溢出的情况。当然也可以用原生的“title属性”,但是太low!
背景
多行文本每个项目处理的方式不一样,这里单独介绍单行文本溢出的场景:
1)当文字溢出时,超出部分显示三个点,el-tooltip组件悬浮显示全部文字;
2)文字未超出时,正常显示,不显示悬浮窗
技术栈
vue项目使用element-ui框架
实现
思路一:使用render函数
本来想着只是单纯的渲染组件,所以就用vue的render函数写,但是写着很快发现不对劲——因为需要文字全部渲染后才知道文字是否溢出,所以只能想别的方法
<script>
import Tooltip from 'element-ui/lib/tooltip.js'
export default {
components:{ Tooltip },
props: { text: String },
data () {
return {
manual: true
}
},
methods: {
render (h) {
const { text } = this.$props
const Text = <div>{text}</div>
const manual = this.textRange(h(Text, text))
const wrapStyle = {
width: '100%'
}
return <div style={wrapStyle}>
<div>{text + ' ' + wrapStyle}</div>
<Tooltip content={text} manual={manual}>
{Text}1900111
</Tooltip>
</div>
}
}
}
</script>
思路二:使用vue自定义指令
既然无法在渲染前获取Dom,那么在渲染的时候获取Dom总可以了吧!但是事实打脸~,得出结论:指令获取的Dom还是虚拟的,也就是还是渲染前虚拟Dom。
<template>
<div class="ellipsis" v-title>
<slot></slot>
</div>
</template>
<script>
import Tooltip from 'element-ui/lib/tooltip.js'
function showOverflowHiddenText (el, value) {
if (el.offsetWidth < el.scrollWidth) {
if (isOver) {
let title = value
if (!value) {
var re1 = new RegExp('<.+?>', 'g')
title = el.innerHTML.replace(re1, '')
}
el.setAttribute('title', title)
}
}
export default {
components: { Tooltip },
props: { text: String },
directives: {
title: {
inserted: (el, binding, vnode) => {
showOverflowHiddenText(el, binding.value ? binding.value.title : '')
},
update: (el, binding, vnode) => {
showOverflowHiddenText(el, binding.value ? binding.value.title : '')
}
}
}
}
</script>
思路三:添加鼠标移入事件(最终思路)
总结思路一的失败教训,本着先渲染才知道是否溢出的原则,给文本元素添加鼠标移入事件来判断溢出才显示浮窗
利用tooltip组件的“manual”属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| manual | 手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效 | Boolean | — | false |
<template>
<div :class="['text-ellipsis',`text-ellipsis_${guid()}`]">
<tooltip :content="text" placement="top" :manual="manual">
<!-- 必须给文本元素进行溢出处理 -->
<div class="ellipsis" @mouseenter="handleMouse">{{text}}</div>
</tooltip>
</div>
</template>
<script>
import Tooltip from 'element-ui/lib/tooltip.js'
export default {
name: 'TextEllispis',
components: { Tooltip },
props: { text: String },
data () {
return {
manual: true
}
},
methods: {
guid () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0
let v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
},
handleMouse (e) /* 鼠标移入事件 */ {
const { target: { scrollWidth, offsetWidth } } = e
this.manual = scrollWidth <= offsetWidth
}
}
}
</script>
判断文本是否溢出还有另外一种方法
handleMouse(e) {
const textRange => (el) {
const textContent = el
const targetW = textContent.getBoundingClientRect().width
const range = document.createRange()
range.setStart(textContent, 0)
range.setEnd(textContent, textContent.childNodes.length)
const rangeWidth = range.getBoundingClientRect().width
return rangeWidth > targetW
}
this.manual = !textRange(e)
}
样式部分
查看样式代码
<style lang="less" scoped>
.ellipsis {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
word-wrap: break-word;
}
.text-ellipsis {
width: 100%;
.ellipsis;
}
</style>

浙公网安备 33010602011771号