低版本ant-design-vue a-tree渲染大数据量卡顿问题 vue虚拟树vue-virt-tree插件解决
如果tree中每条数据需要操作时请使用content插槽,因为使用default插槽会变成列表模式默认全收起且无展开操作按钮,需要调用内置方法进行展开或收起。浏览器对于body高度是有最大限制的,当网页高度超出16777200px后无法显示后续内容。经过测试,数据大致在37万条后,就无法再显示后续内容。使用大量数据的时候,建议使用 shallowRef 来声明list,减少响应式数据内存的暴增。
·
引言
- ant-design-vue 1.x与2.x版本中的a-tree组件不支持虚拟滚动,所以在加载大数据量场景下会造成页面渲染卡顿卡死现象,但在ant-design-vue 3.x版本后使用
height
属性则切换为虚拟滚动。当然,升级版本兼容性问题可能带来更大的工作量,所以这里推荐一个第三方插件vue-virt-list来解决大数据量卡顿问题
虚拟列表的核心原理
- 可视区域渲染(视窗技术)
- 动态计算渲染范围与位置
- 减少 DOM 节点数量的优化机制
vue-virt-list 的特性
- 轻量级与高性能、满帧率、百万数据
- vue2与 Vue 3 的兼容性
- 丰富的自定义配置选项
- vue虚拟列表 [vue-virtual-list]
- vue虚拟滚动列表[vue-virtual-scroll-list]
- vue虚拟树 [vue-virt-tree]
安装与基本使用
- 通过 npm 安装
npm install vue-virt-list -S
- vue-virt-tree基础代码示例
<script lang="ts" setup>
import { onMounted, ref, shallowRef } from 'vue';
import { VirtTree } from 'vue-virt-list';
import 'vue-virt-list/lib/assets/tree.css';
type Data = {
id: string | number;
title: string;
children?: Data;
}[];
const customFieldNames = {
key: 'id',
};
const list = shallowRef<Data>([]);
onMounted(() => {
list.value = Array.from({ length: 40 }).map((_, i) => ({
id: String(i),
title: `Node-${i}`,
children: Array.from({ length: 3 }).map((_, index) => ({
id: `${i}-${index}`,
title: `Node-${i}-${index}`,
children: Array.from({ length: 2 }).map((_, indexChild) => ({
id: `${i}-${index}-${indexChild}`,
title: `Node-${i}-${index}-${indexChild}`,
})),
})),
}));
});
const virtTreeRef = ref<typeof VirtTree>();
</script>
<template>
<div class="demo-tree">
<div class="virt-tree-wrapper">
<VirtTree
ref="virtTreeRef"
:list="list"
:fieldNames="customFieldNames"
:indent="20"
expandOnClickNode
>
<template #empty>
<div style="padding: 16px">暂无数据</div>
</template>
</VirtTree>
</div>
</div>
</template>
<style scoped lang="scss">
.demo-tree {
width: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
.tree-btn-container {
display: flex;
flex: 1;
flex-direction: row-reverse;
justify-content: space-between;
padding: 12px 8px;
gap: 8px;
.input-label {
font-size: 14px;
}
.btn-item {
padding: 4px 12px;
cursor: pointer;
border: 1px solid #ececec;
border-radius: 4px;
font-size: 14px;
}
.input-container {
display: flex;
gap: 8px;
align-items: center;
input {
height: 100%;
border: 1px solid #ececec;
border-radius: 4px;
padding: 0 8px;
}
}
}
}
</style>
注意2点:
浏览器对于body高度是有最大限制的,当网页高度超出16777200px后无法显示后续内容。经过测试,数据大致在37万条后,就无法再显示后续内容。
使用大量数据的时候,建议使用 shallowRef 来声明list,减少响应式数据内存的暴增
插槽使用 注意事项
如果tree中每条数据需要操作时请使用content插槽,因为使用default插槽会变成列表模式默认全收起且无展开操作按钮,需要调用内置方法进行展开或收起
<template>
<div class="demo-tree">
<div class="virt-tree-wrapper">
<VirtTree
ref="virtTreeRef"
:list="list"
:fieldNames="customFieldNames"
:indent="30"
>
<template #content="{ node }">
<div>
<div>
<span>level: {{ node.level }}; </span>
<span>title: {{ node.data.name }}</span>
</div>
<div class="item-option">
<a-icon type="EditOutlined" />
</div>
</div>
</template>
<template #empty>
<div style="padding: 16px">暂无数据</div>
</template>
</VirtTree>
</div>
</div>
</template>
更多推荐
所有评论(0)