项目需求:
el-cascader中的文字超出范围时,超出的部分会自动以...显示,要求在超出时鼠标移上去时用el-tooltip显示完整的内容,未超出范围则不显示。
踩坑经历:
拿到该需求时,首先去elementUI文档查看是否有提供相应API,嗯...没有。没有相应API就只能自己想办法了。
该页面结构如下:
<el-tooltip effect="dark" :disabled="disabledTooltip" :content="contentText" placement="top">
<el-cascader />
</el-tooltip>
其中contentText是用户在cascader中的选择,disabledTooltip则是判断tooltip是否要显示
思路1:通过ref获取tooltip和cascader的长度进行判断。
结果:不过contentText中是什么,获取的宽度都是固定的,该思路PASS。
思路2:通过获取el-cascader的宽度,再获取contentText的长度,进行换算后再进行比较。
结果:由于contentText中并不是只有中文,还有数字,英文,特殊字符等,而它们的长度又都不是一样的,所以该方法可以使可以,但是会有误差。
最终解决方案:
我在查看元素结构时,发现tooltip最终渲染到页面上时会有一个el-tooltip__popper类,于是为cascader添加了一个鼠标移入事件,通过querySelectorAll获取该元素的clientWidth。发现可以正确获取长度,但是有时获取到的却是0,用了nextTick后还是一样,没办法,只能上延时函数了,上延时函数后就可以正确获取了。
不过要注意的是,在获取前要把tooltip显示出来,才能正确获取,然后通过延时函数来决定是否显示,这就要注意下延时函数的延时时间,我测试后设置的是10毫秒,这样即可以正确获取宽度,也可以在不显示tooltip时迅速关闭tooltip,而不会出现痕迹。
代码如下
<template>
<el-tooltip ref="tipRef" :disabled="disabledTooltip" class="item" effect="dark" :content="contentText" placement="top">
<el-cascader
v-model="fullcategorypath"
:options="categoryItems"
size="mini"
:props="props"
:disabled="disabled"
:clearable="clearable"
style="width: 100%"
@mouseover.native="tooltipHover"
/>
</el-tooltip>
</template>
<script>
export default {
props: {
value: {
type: [Array, String, Number],
default: null
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
}
},
data() {
return {
fullcategorypath: [],
categoryItems: [],
contentText: '',
disabledTooltip: true,
}
},
methods: {
tooltipHover() {
if (!this.disabledTooltip) {
const inputWidth = this.$refs.tipRef.$el.clientWidth
setTimeout(() => {
const tooltipWidth = document.querySelectorAll('.el-tooltip__popper')[document.querySelectorAll('.el-tooltip__popper').length - 1].clientWidth
if ((tooltipWidth + 30) >= inputWidth) {
this.disabledTooltip = false
} else {
this.disabledTooltip = true
}
}, 10)
}
}
}
}
</script>
tooltipWidth之所以要加30是因为有margin,具体数字要根据自己实现项目来。
|