el-table自定义单行超出显示省略号,鼠标移动显示tooltip(文本内容超出显示)
1、需求
el-table单行显示,文本内容超出显示省略号,鼠标移动到所在行列弹出tooltip显示全文(只有文本内容超出弹出显示,否则不弹出tooltip)。
2、思路方法
一开始是想着直接使用el-table自带show-overflow-tooltip属性,但发现自带的tooltip不会换行,如果文本内容太长,会全屏显示一长行,不太美观,这种可以通过全局样式改变,但会污染其他tooltip样式,最后通过el-table的
tooltip-effect属性给tooltip添加自定义类名,然后通过给类设置css控制tooltip长度;
第二种是使用el-tooltip组件,但也会有个问题就是不管内容超没超出,只要鼠标移动到所在行列都会显示tooltip,解决这个问题的方法就是使用鼠标移入事件mouseenter给所在父级添加一个隐藏的div,把内容赋值给隐藏的div,node.target长度与新增div长度作比较,进而判断文本有没有超出,超出就显示tooltip,否则tooltip就设置为disable不显示;
3、解决方案
3.1、el-table自带show-overflow-tooltip属性方法
给要显示的table行添加show-overflow-tooltip
属性
<el-table-column
v-for="(column, index) in showColumns"
:label="column.label"
:min-width="getTableminWidth(column.key)"
:prop="column.key"
:key="column.key"
:align="index ? 'center' : 'left'"
:show-overflow-tooltip="column.showTooltip">
</el-table-column>
给el-table添加tooltip-effect
属性
<!-- 给table添加tooltip-effect属性,
dark是主题;
custom-tooltip-effect自定义主题会给tooltip添加一个custom-tooltip-effect类名 -->
<el-table
v-loading="loading"
row-key="clauseId"
:data="clauseList"
ref="multipleTable"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
:row-class-name="rowClassNameFun"
tooltip-effect="dark custom-tooltip-effect"
@select="select"
@select-all="selectAll"
>
table添加这个属性后会给弹出的tooltip添加一个自定义类名tooltip-effect
,给这个类设置样式即可设置tooltip样式
给类添加样式
注:样式注意不要添加scoped,不然会不起效,建议提到公共样式表中
<style lang="scss">
.custom-tooltip-effect{
max-width: 600px;
line-height: 23px;
}
</style>
效果图:
添加样式前:
添加样式后:
3.2、el-tooltip组件自定义方法
添加自定义el-tooltip组件,通过disabled属性控制显不显示tooltip(:disabled="curRowClauseId == scope.row.clauseId && !isShowTooltip"
)
<el-table-column
v-for="(column, index) in showColumns"
:label="column.label"
:min-width="getTableminWidth(column.key)"
:prop="column.key"
:key="column.key"
:align="index ? 'center' : 'left'"
:show-overflow-tooltip="column.showTooltip"
>
<template v-slot="scope">
<el-tooltip
placement="top"
class="review-table-small-tooltip-span"
v-if="column.key == 'clauseName' && scope.row[column.key]"
:disabled="curRowClauseId == scope.row.clauseId && !isShowTooltip"
>
<!-- 给review-table-tip-box添加样式达到换行 -->
<div
slot="content"
class="review-table-tip-box"
:raw-content="true"
>
{{ scope.row[column.key] }}
</div>
<!-- 添加移入事件 -->
<div
class="review-table-ellipsis"
@mouseenter="mouseenterChange($event, scope.row.clauseId)"
>
{{ scope.row[column.key] }}
</div>
</el-tooltip>
<span v-else class="review-table-row">
{{ scope.row[column.key] }}
</span>
</template>
</el-table-column>
事件方法:需添加一个当前行id(curRowClauseId )进行判断,不然会造成table抖动问题
/** 判断标签内容是否超出标签宽度,超出则显示tooltip */
mouseenterChange(event, clauseId) {
const node = event.target;
const nodeContentWidth = getNodeContentWidth(node);
const nodeWidth = node.clientWidth;
if (nodeContentWidth >= nodeWidth) {
// 如果childNodes下的text宽度等于元素宽度 文字溢出
this.isShowTooltip = true;
} else {
// 否则为不溢出
this.isShowTooltip = false;
}
/**
* 如果不添加curRowClauseId进行判断会导致表格抖动问题
* 原因时因为鼠标移入到第一个表格行时,isShowTooltip就是true,
* 当鼠标移入到第二个表格行时,isShowTooltip先是true,导致tooltip先显示,再会根据第二行文本长度判断是否显示
* 就会导致出现先是显示tooltip,后又隐藏进而导致表格抖动问题
*/
this.curRowClauseId = clauseId;
},
隐藏元素建议插入到元素的父元素中,插入到body中可能会导致文本内容样式有太大变化,进而长度对不上问题。
/**
* @description: 传入元素节点,获取元素节点内容实际宽度
* @param {*} node 元素节点
* @return {*} width 元素内容宽度
*/
export function getNodeContentWidth(node) {
// 创建临时元素
const tempElement = document.createElement("span");
tempElement.style.visibility = "hidden"; // 确保元素不可见
tempElement.style.position = "absolute"; // 确保元素脱离文档流
// 将div内容复制到临时元素
tempElement.textContent = node.textContent;
// 将临时元素添加到传入元素的父元素中
node.parentNode.appendChild(tempElement);
// 获取宽度
const width = tempElement.clientWidth;
// 移除临时元素
node.parentNode.removeChild(tempElement);
return width;
}
review-table-tip-box样式:
效果图:
4、总结
第一种方案比较方便,但仅限于el-table;第二种方案比较繁琐,一般不会用到,在el-table,el-collapse都能使用。