visactor vTable 在移动端支持 ellipsis 气泡

前言:

为了优化用户体验

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. 总结

提供的两个解决思路性能消耗都不大,都可以满足需求。

相关推荐
LucianaiB10 小时前
【元宝搜索开发者征文大赛】AI时代,学得慢就不用学?用元宝搜索打造一个教程保质期,确保每一个教程符合你的现状
前端·人工智能·ai编程
excel10 小时前
JavaScript 对象池:减少高频对象创建与 GC 压力
前端
陈随易11 小时前
纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS
前端·后端·程序员
子兮曰13 小时前
Chrome 权限元素实战:144 与 151 的渐进增强写法
前端·javascript·chrome
IT_陈寒13 小时前
Redis连接池泄漏那次,我差点把生产环境搞崩了
前端·人工智能·后端
强尼银手13 小时前
我花一天做了个格斗游戏原型,判定全对,然后被「美术」劝退了
前端·javascript
石小石Orz13 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
陈随易14 小时前
专注飞机 FocusFlight,两个人把番茄钟做成了一趟航班
前端·后端·程序员
总要学点什么15 小时前
第98篇:三维特效-材质线效果——给一条线换十种材质,虚线的图案只填了一半
开发语言·前端·javascript·ecmascript·gis·webgl·材质
10share15 小时前
基于大模型的 i18n 方案:把中文原文当 Key,轻松搞定多语言维护
前端·vue.js