前言:
为了优化用户体验
VTable 内部在移动端故意屏蔽了省略号气泡的展示
本文旨在提供相对体验较好的移动端的 ellipsis 气泡展示完整信息的解决方案
1. 配置好 ref,以供引用
html
<template>
<VTable
:id="uid"
ref="tableRef"
v-bind="$attrs"
/>
</template>
Typescript
const tableRef = ref();
2. 判断当前 cell 是否是溢出的
Typescript
function isCellTextOverflow(tableInstance: any, col: number, row: number): boolean {
// getCellOverflowText 返回非空字符串说明有溢出
const overflowText = tableInstance.getCellOverflowText(col, row);
return !!overflowText;
}
3. 展示气泡
有 2 种方案,优缺点比较如下表:
| 气泡方案 | VTable 原生气泡 | 自定义气泡 |
|---|---|---|
| 优点 | 配置简单 出现的位置不需要大量计算 | 长的好看 用户操作灵活 点击滚动等就会及时消失 |
| 缺点 | 样式丑 用户操作不灵活,不会及时消失 | 配置繁琐 |
3.1 VTable 原生气泡
3.1.1 开启 tooltip 开关
如果可以在初始化配置 VTable 的 config 的话 直接在初始化的时候,把 config.tootip.isShowOverflowTextTooltip 配置为 true 即可。
如果开发没有配置 VTable config 的初始化权限的话,也可以在 VTable 初始化好后,通过 updateOption 来更新配置,注意不要覆盖掉原生的其他配置项。
Typescript
const tableInstance = tableRef.value?.table;
tableInstance.updateOption({
...tableInstance.options,
tooltip: {
...tableInstance.options.tooltip,
isShowOverflowTextTooltip: true,
}
});
3.1.2 监听用户的点击事件展示 tooltip
Typescript
import { TABLE_EVENT_TYPE } from '@visactor/vtable';
tableInstance.on(TABLE_EVENT_TYPE.CLICK_CELL, (args: any) => {
const isOverflow = isCellTextOverflow(tableInstance, col, row);
if (!isOverflow) {
return;
}
setTimeout(() => {
// 调用内部 TooltipHandler 手动显示气泡
// 注意:internalProps 是内部属性,使用时需要注意 TypeScript 类型兼容(如需)
tableInstance.internalProps.tooltipHandler.showTooltip(col, row);
}, 10);
});
点击有溢出的 cell,就会在 cell 附近展示出来的 VTable 原生的气泡了,长得还是有点丑的,如果要用的话,建议在 VTable 的 option 里加点样式的配置。
另外这个气泡的消失逻辑是 VTable 原生自己控制的,灵敏度也较一般,不会及时消失,有精力也可画时间监听优化,调用 VTable 原生函数的隐藏方法。
3.2 自定义 DIV 展示 tooltip
3.2.1 写个自定义的 div
HTML
<div v-if="tooltipTxt" :style="{ left, top }" class="custom-popup">
{{ tooltipTxt }}
</div>
Typescript
const tooltipTxt = ref('');
const left = ref('0px');
const top = ref('0px');
配个好看点的气泡样式
SCSS
.custom-popup {
position: fixed;
z-index: 10;
background: rgba(0, 0, 0, 0.65);
color: #fff;
border-radius: 4px;
padding: 4px 8px;
&::after {
content: '';
width: 0;
height: 0;
/* 边框宽度:上4px | 右4px | 下4px | 左0(仅右边框有宽度) */
border-width: 4px 4px 4px 0;
border-style: solid;
/* 边框颜色:上透明 | 右灰色 | 下透明 | 左透明(仅右边框显示) */
border-color: transparent #333 transparent transparent;
/* 消除默认空白(避免字体/行高导致的间隙) */
line-height: 0;
font-size: 0;
left: -6px;
top: 0;
bottom: 0;
margin: auto;
position: absolute;
}
}
3.2.2 监听并且展示自定义气泡
Typescript
tableInstance.on('click_cell', (args: any) => {
// 先把旧的气泡干掉
tooltipTxt.value = '';
const { col, row, value } = args;
// 过滤非数据行
if (col < 0 || row < 0) return;
// 判断是否溢出
const isOverflow = isCellTextOverflow(tableInstance, col, row, value);
if (!isOverflow) {
return;
}
// 1. 获取列宽
const colWidth = tableInstance.getColWidth(col);
// 1. 获取列高
const colHeight = tableInstance.getRowHeight(col);
const { offsetX, offsetY } = args.event;
left.value = offsetX - colWidth * 0.2 + 'px';
top.value = offsetY - colHeight / 2 + 'px';
tooltipTxt.value = value;
});
3.2.3 监听点击/滚动事件 隐藏气泡
Typescript
import { TABLE_EVENT_TYPE } from '@visactor/vtable';
const hideTooltip = () => {
if (tooltipTxt.value) {
tooltipTxt.value = '';
}
};
const tableInstance = tableRef.value?.table;const tableInstance = tableRef.value?.table;
tableInstance.on(TABLE_EVENT_TYPE.SCROLL, hideTooltip);
tableInstance.on(TABLE_EVENT_TYPE.RESIZE_COLUMN, hideTooltip);
// 监听树形结构变化(展开/折叠触发时也强制关掉,双重保险)
tableInstance.on(TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, hideTooltip);
// 如果你用了自动高度的方案,建议也监听 UPDATED
tableInstance.on(TABLE_EVENT_TYPE.UPDATED, hideTooltip);
onMounted(() => {
window.addEventListener('scroll', hideTooltip, true);
});
onUnmounted(() => {
window.removeEventListener('scroll', hideTooltip, true);
});
4. 总结
提供的两个解决思路性能消耗都不大,都可以满足需求。