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

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

相关推荐
程序员清洒10 分钟前
Flutter for OpenHarmony:GridView — 网格布局实现
android·前端·学习·flutter·华为
VX:Fegn089513 分钟前
计算机毕业设计|基于ssm + vue超市管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
0思必得022 分钟前
[Web自动化] 反爬虫
前端·爬虫·python·selenium·自动化
LawrenceLan32 分钟前
Flutter 零基础入门(二十六):StatefulWidget 与状态更新 setState
开发语言·前端·flutter·dart
秋秋小事1 小时前
TypeScript 模版字面量与类型操作
前端·typescript
2401_892000521 小时前
Flutter for OpenHarmony 猫咪管家App实战 - 添加提醒实现
前端·javascript·flutter
Yolanda941 小时前
【项目经验】vue h5移动端禁止缩放
前端·javascript·vue.js
广州华水科技3 小时前
单北斗GNSS形变监测一体机在基础设施安全中的应用与技术优势
前端
EndingCoder3 小时前
案例研究:从 JavaScript 迁移到 TypeScript
开发语言·前端·javascript·性能优化·typescript
阿珊和她的猫4 小时前
React 路由:构建单页面应用的导航系统
前端·react.js·状态模式