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 开关

如果可以在初始化配置 VTableconfig 的话 直接在初始化的时候,把 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 原生的气泡了,长得还是有点丑的,如果要用的话,建议在 VTableoption 里加点样式的配置。

另外这个气泡的消失逻辑是 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. 总结

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

相关推荐
GreenTea1 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
渣渣xiong2 小时前
从零开始:前端转型AI agent直到就业第五天-第十一天
前端·人工智能
布局呆星2 小时前
Vue3 | 组件通信学习小结
前端·vue.js
C澒2 小时前
IntelliPro 企业级产研协作平台:前端智能生产模块设计与落地
前端·ai编程
OpenTiny社区3 小时前
重磅预告|OpenTiny 亮相 QCon 北京,共话生成式 UI 最新技术思考
前端·开源·ai编程
前端老实人灬3 小时前
web前端面试题
前端
Moment3 小时前
AI 全栈指南:NestJs 中的 Service Provider 和 Module
前端·后端·面试
IT_陈寒3 小时前
为什么我的JavaScript异步回调总是乱序执行?
前端·人工智能·后端
Moment3 小时前
AI全栈入门指南:NestJs 中的 DTO 和数据校验
前端·后端·面试