VTable 支持展开收拢自动拉长不展示内部滚动条

21 阅读1分钟

前言

VTable 在文档流里面

tree 形的展开 / 收拢后,会在内部展示滚动条,不会自动舒展开

本文旨在提供一个优化 UI 效果的技术方案

时间有限 直接贴代码了

<template>
  <div>
    <VTable
      ref="tableRef"
      v-bind="$attrs"
    />
  </div>
</template>

<script lang="ts" setup>
import { TABLE_EVENT_TYPE } from '@visactor/vtable';

const tableRef = ref();

// 1. 定义调整高度的核心逻辑
const adjustHeight = () => {
  const tableInstance = tableRef.value?.table;
  // 放入 nextTick 以确保 VTable 内部渲染已完成,拿到最新高度
  requestAnimationFrame(() => {
    const totalHeight = tableInstance.getAllRowsHeight();
    if (tableInstance.canvasHeight !== totalHeight) {
      tableInstance.options.canvasHeight = totalHeight;
      tableInstance.setCanvasSize(tableInstance.canvasWidth, totalHeight);
    }
  });
};

const tableInstance = tableRef.value?.table;

const oldTheme = tableInstance.options.theme || {};

// PS: IMPORTNT: 挑个时间执行下列逻辑
// 隐藏任何形态下的滚动条,没有这坨会导致展开的时候会有一闪而过的滚动条
tableInstance.updateOption({
    ...tableInstance.options,
    theme: {
      ...oldTheme, // 展开保留旧属性
      scrollStyle: {
        ...(oldTheme.scrollStyle || {}), // 保留旧的 scrollStyle 其他属性(如有)
        visible: 'none',
      },
    },
});

// 2. 劫持 setRecords 方法(这是 expandAllRows props 底层调用的方法)
const originalSetRecords = tableInstance.setRecords.bind(tableInstance);
tableInstance.setRecords = function (records: any, options: any) {
    // 先执行原有逻辑
    originalSetRecords(records, options);
    // 然后手动触发我们调整高度的逻辑
    adjustHeight();
};
// 3. 同时也监听常规的交互事件(点击展开/收起)
tableInstance.on(TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, adjustHeight);
// 4. 监听初始化
tableInstance.on(TABLE_EVENT_TYPE.INITIALIZED, adjustHeight);