antd vue table ellipsis不生效的原因及解决方案

986 阅读2分钟

背景:今天跑起公司的项目,看到同事做的页面的样式和我本地的不一样,询问之下原来是版本不一致,同事的已经是antd的v3.2.3了,但是我还是项目创建之初的v3.0.0-beta,(不得不说被坑了,偷偷升级不告诉我,可恶啊),遂升级antd ui至最新的版本v3.2.10,想着应该不会有什么问题,毕竟都是稳定版,结果发现在table组件里配置了ellipsis的表格只会省略,鼠标hover以后并不会显示完整的信息。

现象解析

v3.2.10的table里产生的td是这样的

image.png

v3.2.3的table里产生的td是这样的

image.png

显而易见,是v3.2.10里的td少添加title在标签上导致的

当然,这里还有一个背景就是,table组件是我们二次封装的,我们自己添加了一层template去做自己的定制化,但是这样写在v3.2.3的版本下是可以正常使用的,代码如下

      <template #bodyCell="{ column, record }">
        <span>
          {{ column.formatter ? column.formatter(record[column.dataIndex]) : record[column.dataIndex] }}
        </span>
      </template>

那为什么到v3.2.10就不可以了呢?直接从源头找原因

源码解析

路径在component/vc-table/Cell/index.tsx

// v3.2.3
      let title: string;
      const ellipsisConfig: CellEllipsisType = ellipsis === true ? { showTitle: true } : ellipsis;
      if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) {
        if (typeof childNode === 'string' || typeof childNode === 'number') {
          title = childNode.toString();
        } else if (isVNode(childNode) && typeof childNode.children === 'string') {
          title = childNode.children; // 关键在于这里
        }
      }
// v3.2.10
      let title: string;
      const ellipsisConfig: CellEllipsisType = ellipsis === true ? { showTitle: true } : ellipsis;
      if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) {
        if (typeof childNode === 'string' || typeof childNode === 'number') {
          title = childNode.toString();
        } else if (isVNode(childNode)) {
          title = getTitle([childNode]); // 关注这一行
        }
      }

分析源码可以发现是在我标注的地方有不一样,从判断条件以及获取方式上都不一样

通过打印我发现childNode.children就是我们自定义展示里的信息的展示

但是在v3.2.10里的getTitle()方法里是这样写的

    const getTitle = (vnodes: VNodeArrayChildren) => {
      const vnode = filterEmpty(vnodes)[0];
      if (isVNode(vnode)) {
        if (vnode.type === Text) {
          return vnode.children;
        } else {
          return Array.isArray(vnode.children) ? getTitle(vnode.children) : undefined; //会进入到这里
        }
      } else {
        return vnode;
      }
    };

vnode.type就是我们自定义展示的标签,如我上面所写的话,就是span,所以会进到else的条件里,但是children又是string,就会undefined,所以我的猜想是如果我自定义里面写的是text标签,那么这个升级并不会暴露这个问题,但是这个对于children是否是Array的判断,我目前还没有想到具体的场景,请有想法的朋友们在评论区一起探讨一下。

总结

这一次问题的产生源于ui库的升级,但是谁也没想到同样是稳定的两个版本竟然有这样的改动,而且官方文档里也没有对自定义展示做出特别的指引,所以在我百般google找不到答案的情况下只能去源码里调试找原因了,但是这次理解源码也只是基于解决这个问题的,对于整个table的思路还是有很多不理解,如果这篇文章有什么写的不对的地方,请给我留言,我一定及时更新。