手撸一个vue虚拟树组件

729 阅读2分钟

前景

由于业务中经常有渲染上万条数据的树结构,在开发中自己也封装了一个虚拟树组件,但是比较乱,现在刚好学了Vue3,想着用Vue3重新撸一个树组件。废话不多说,直接开干!

核心思想

其原理是通过监听滚动条,实时的计算并渲染树节点。而滚动条的呈现是通过给元素加paddingTop值来实现,根据当前scrollTop为多少,来计算对应的paddingTop。

通过这个原理,首先需要实现一个virList虚拟滚动组件,由于虚拟组件要监听滚动事件,动态替换node节点,所以需要知道每个节点的高度,因此需要定义一个每个节点的高度 size 以及需要渲染的节点个数 remain ,然后根据 scrollTop/size 来计算需要截取源数据的start下标 首次加载和滚动条滚动时,都要去计算paddingTop值和截图之后的渲染数据。

image.png

对于树形数据,我们首先要做的就是要把树状的数据拍平,变成列表的数据,对于节点左边的偏移,整体要展现树型的形状,则通过拍平时赋予的 level 来决定,表示为第几层子节点,等于0即表示为当前是根节点。转成平级列表之后其他操作就容易了。

功能列表

  •  大数据量支持虚拟滚动
  •  基本树形数据的展示
  •  支持checkbox选择
  •  支持懒加载
  •  默认展开和默认选中
  •  禁用节点
  •  通过多种方式选中节点和获取选中的节点信息
  •  支持自定义节点内容(渲染函数、插槽)
  •  支持自定义加载和展开图标
  •  checkbox父子节点可设置是否联动
  •  提供单独的虚拟列表使用

我封装好发布到npm了,有兴趣可以去直接看看gitHub源码

使用文档看这里

基本使用

打包成组件后,发布npm,通过

npm i vue-virtree

安装 全局注册, 但这会丢失类型,如果你用了typescript, 不推荐这种方式

import { createApp } from 'vue';
import VirTree from 'vue-virtree';

createApp(App).use(VirTree).mount('#app');

In components:
<vir-tree />

局部注册, 可以获得完整的类型

<template>
  <div class="demo">
    <vir-tree" :source="list" />
  </div>
</template>

<script lang="tsx">
  import {defineComponent, onMounted, ref} from 'vue';
  import { VirTree, TreeNodeOptions } from 'vue-virtree';

  export default defineComponent({
    name: 'BaseDemo',
    components: { VirTree },
    setup(props, {emit}) {
      const list = ref<TreeNodeOptions[]>([]);
      return {
        list
      }
    }
  });
</script>