vue-project-tree

使用 Vue3 + TS 实现的树形结构展示组件,有拖拽、排序、自定义图标等功能
1,178 3
Install
npm install vue-project-tree
Latest Version:1.4.0
Vue:3
License:MIT
Last Updated:May 25, 2026
Links: GitHub  ·  npm
Maintainer: one-ccs

vue-project-tree

基于 Vue 3 + TypeScript 实现的树形展示组件,零第三方依赖。 支持 拖拽、排序、节点过滤、多选、自定义图标 等功能,并可通过覆写内置 CSS 变量 灵活定制节点样式。

预览图 预览图

一、使用

  1. 安装

npm install vue-project-tree -S

  1. 导入

import VueProjectTree from "vue-project-tree";

  1. 使用

3.1. 工程化环境

<script setup lang="ts">
import { ref } from 'vue';
import VueProjectTree from 'vue-project-tree';
import 'vue-project-tree/style.css';

interface TreeNode extends NodeData {
  id?: number;
  label?: string;
  children?: TreeNode[];
}

const data = ref<TreeNode[]>([
  {
    id: 1,
    label: '1',
    children: [
      {
        id: 2,
        label: '2',
        children: [
          {
            id: 3,
            label: '3',
          },
          {
            id: 4,
            label: '4',
          },
        ],
      },
      {
        id: 5,
        label: '5',
      },
    ],
  },
  {
    id: 6,
    label: '6',
  },
  {
    id: 7,
    label: '7',
  },
]);
</script>

<template>
  <vue-project-tree :data="data"></vue-project-tree>
</template>

3.2. 非工程化环境

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vue-project-tree</title>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="vue-project-tree.css" />
  </head>
  <body>
    <div id="app">
      <vue-project-tree :data="data" checkbox node-icon></vue-project-tree>
    </div>

    <script type="importmap">
      {
        "imports": {
          "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
        }
      }
    </script>
    <script type="module">
      import { createApp, ref } from 'vue';
      import VueProjectTree from './vue-project-tree.js';

      const data = ref([
        {
          id: 123,
          label: 123,
          children: [
            {
              id: 456,
              label: 456,
              children: [
                {
                  id: 789,
                  label: 789,
                },
              ],
            },
          ],
        },
      ]);

      createApp({
        components: {
          VueProjectTree,
        },
        data() {
          return {
            data,
          };
        },
      }).mount('#app');
    </script>
  </body>
</html>

二、API

1、属性

名称 说明 类型 默认值
data 树形数据,最外层必须是数组 Array
idKey? 主键属性名(值在树中必须唯一) string "id"
labelKey? 标签属性名 string "label"
childrenKey? 子节点数组属性名 string "children"
indent? 左侧缩进值 number | string 24
nodeHeight? 节点高度 number | string 35
highlightCurrent? 是否高亮当前选中节点 boolean true
expandIcon? 是否显示展开图标 boolean true
expandIconSize? 展开图标大小 number | string 10
expandIconHold? 没有子节点时展开节点的显示逻辑 'show' | 'hide' | 'hold' show
expandWithClick? 是否在点击节点时展开 boolean true
expandHoverTime? 拖拽时在节点上悬停多少毫秒展开该节点 number 380
checkbox? 是否显示复选框 boolean false
checkboxSize? 复选框大小 number | string 20
nodeIcon? 是否显示节点图标 boolean false
nodeIconSize? 节点图标大小 number | string 20
filterMethod? 过滤方法(需手动调用 filter 函数执行过滤) Function (value: any, data: NodeData) => true
draggable? 是否允许拖拽 boolean false
allowDrag? 节点是否拖拽放下处理函数(返回 true 表示允许拖拽) Function (data: NodeData) => false
allowDrop? 节点是否允许放下处理函数(返回 true 表示允许放下) Function (data: NodeData) => false
dropOffset? 放下位置偏移量 number 8

2、事件

| 事件名 | 说明 | 回调参数 | | ----------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | nodeClick | 节点点击事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | nodeDblclick | 节点双击事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | nodeRightClick | 节点右键点击事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | currentDataChange | 当前节点改变事件 | (data: NodeData | undefined) 节点数据 | | start | 拖拽开始事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | enter | 拖拽进入事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | over | 拖拽进入后在节点内持续触发 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | leave | 拖拽离开事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement) 分别为事件数据,节点数据,节点元素 | | dropped | 节点放下事件 | (event: DragEvent, data: NodeData, nodeElement: HTMLElement, extraData: DroppedExtraData) 分别为事件数据,节点数据,节点元素,额外数据(type: 拖拽放下位置, isPreventDefault: 是否阻止默认操作, preventDefault: 调用后阻止默认操作, _default?: 调用后立即执行默认操作(仅放下子事件拥有)) | | droppedBefore | 放在节点前事件 | (event: DragEvent, dragData: NodeData[], dropData: NodeData, extraData: DroppedExtraData) 分别为事件数据,拖拽节点数据列表,放下节点数据,额外数据(type: 拖拽放下位置, isPreventDefault: 是否阻止默认操作, preventDefault: 调用后阻止默认操作, _default?: 调用后立即执行默认操作(仅放下子事件拥有 | | droppedIn | 放在节点内事件 | (event: DragEvent, dragData: NodeData[], dropData: NodeData, extraData: DroppedExtraData) 分别为事件数据,拖拽节点数据列表,放下节点数据,额外数据(type: 拖拽放下位置, isPreventDefault: 是否阻止默认操作, preventDefault: 调用后阻止默认操作, _default?: 调用后立即执行默认操作(仅放下子事件拥有 | | droppedAfter | 放在节点后事件 | (event: DragEvent, dragData: NodeData[], dropData: NodeData, extraData: DroppedExtraData) 分别为事件数据,拖拽节点数据列表,放下节点数据,额外数据(type: 拖拽放下位置, isPreventDefault: 是否阻止默认操作, preventDefault: 调用后阻止默认操作, _default?: 调用后立即执行默认操作(仅放下子事件拥有 | | end | 拖拽结束事件 | (event: DragEvent, data: [NodeData, NodeData], nodeElement: [HTMLElement, HTMLElement]) 分别为事件数据,[开始节点数据,结束节点数据],[开始节点元素,结束节点元素] |

3、方法

方法 描述 参数 返回值
getMultipleList 获取多选列表 NodeData[]
setMultipleList 设置多选列表 (dataList: NodeData[]) 需要多选的节点列表
clearMultipleList 清除多选列表
toggleChecked 切换节点选中状态 (data: NodeData) 节点数据
toggleExpanded 切换节点展开状态 (data: NodeData) 节点数据
expandAll 展开所有节点
collapseAll 收起所有节点
filter 立即调用 filterMethod 对节点进行过滤 (value: any) 作为 filterMethod 的第一个参数
findById 通过节点主键值查找节点数据 (id: string | number) 节点主键值 NodeData | null
getParents 获取节点的所有父节点数据列表 (data: NodeData) 节点数据 NodeData[]
getParent 获取节点的父节点数据,没有则返回 null (data: NodeData) 节点数据 NodeData | null
getAllChildren 获取节点的所有子节点数据列表 (data: NodeData) 节点数据 NodeData[]
getChildren 获取节点的子节点数据列表 (data: NodeData) 节点数据 NodeData[] | undefined
hasChild 递归判断父节点是否包含该子节点 (parent: NodeData, data: NodeData) 分别为父节点数据,子节点数据 boolean
removeData 移除节点 (dataList: NodeData[]) 节点数据列表
insertData 插入节点 (parentData: NodeData, dataList: NodeData[], insertIndex = 0) 分别为父节点数据,节点数据列表,插入的下标(默认 0)
moveBefore 移动到节点前 (dragData: NodeData[], dropData: NodeData) 分别为拖拽节点数据列表,放下节点数据 移动后的节点索引
moveIn 移动到节点内 (dragData: NodeData[], dropData: NodeData) 分别为拖拽节点数据列表,放下节点数据 移动后的节点索引
moveAfter 移动到节点后 (dragData: NodeData[], dropData: NodeData) 分别为拖拽节点数据列表,放下节点数据 移动后的节点索引

4、插槽

插槽名 说明 域
expandIcon 自定义展开图标 { data, size } 分别为节点数据,展开图标大小
checkbox 自定义复选框 { data, size } 分别为节点数据,复选框大小
nodeIcon 自定义节点图标 { data, size } 分别为节点数据,节点图标大小
label 自定义节点标签 { data } 节点数据

5、CSS 变量

名称 说明 默认值
--color 文本颜色 #666666
--color-current 当前选中节点文本颜色 #4C74F6
--color-drop-in 放入节点文本颜色 #fff
--bg-color 背景色 transparent
--bg-color-current 当前选中节点背景色 #E0EFFF
--bg-color-checked 选中节点背景色 #E0EFFF
--bg-color-hover 悬停节点背景色 #0000000a
--bg-color-drop-in 放入节点背景色 #409eff

6、注意事项

  • 拖动节点时,若页面样式发生变动,会导致节点错位,进而导致拖拽事件不完整,致使节点样式错乱或数据丢失。

Related Packages

sl-vue-tree

draggable tree vue component

116,055
sl-vue-tree-next

draggable tree vue component

12,243 13
vue-sortable-list

Vue directive for lists allowing draggable sorting in sync.

2,935 2
@he-tree/vue

Vue tree component. Features: Vue2 & 3, TypeScript, SSR, nested, virtual list, d...

634,779 316
vue3-sortable

Vue 3 sortable lists

10,440 5

Version History

Version Released Vue License
1.4.0 ^3.5.13 MIT
1.3.4 ^3.5.13 MIT
1.3.3 ^3.5.13 MIT
1.3.1 ^3.4.21 MIT
1.2.0 ^3.4.21 MIT
Pre-releases (2)
Version Released Vue License
1.3.1-alpha.1 ^3.5.13 MIT
1.3.1-alpha ^3.5.13 MIT