前言
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);