更新记录

1.0.0(2025-11-14)

  • 三级树形结构:支持章节、节、小节三级嵌套
  • 拖拽排序:支持触摸拖拽排序,带有层级限制
    • 章节只能与章节交换位置
    • 节只能在本章下的节之间交换位置
    • 小节只能在本节下的小节之间交换位置
  • 折叠展开:支持章节和节的展开/折叠功能
  • 操作功能:提供重新生成、编辑、删除、添加要求等操作
  • 权限控制:支持禁用拖拽和编辑功能
  • 手机端优化:完美适配移动端,响应式设计
  • 拖拽指示:拖拽时显示指示线,提供视觉反馈

平台兼容性

uni-app(4.84)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟

uni-app x(4.84)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

el-tree

一个支持拖拽排序的三级树形结构组件,适用于 uni-app 项目。主要用于章节目录管理场景,支持章节、节、小节三级结构的拖拽排序和折叠展开。

功能特性

  • 三级树形结构:支持章节、节、小节三级嵌套
  • 拖拽排序:支持触摸拖拽排序,带有层级限制
    • 章节只能与章节交换位置
    • 节只能在本章下的节之间交换位置
    • 小节只能在本节下的小节之间交换位置
  • 折叠展开:支持章节和节的展开/折叠功能
  • 操作功能:提供重新生成、编辑、删除、添加要求等操作
  • 权限控制:支持禁用拖拽和编辑功能
  • 手机端优化:完美适配移动端,响应式设计
  • 拖拽指示:拖拽时显示指示线,提供视觉反馈

安装使用

1. 引入组件

在页面中引入组件:

<template>
    <view class="container">
        <el-tree 
            :data="treeData"
            :draggable="draggable"
            :editable="editable"
            @change="onTreeChange"
            @regenerate="onRegenerate"
            @edit="onEdit"
            @delete="onDelete"
            @addRequirement="onAddRequirement"
        ></el-tree>
    </view>
</template>

<script>
import ElTree from '@/uni_modules/el-tree/components/el-tree/el-tree.vue'

export default {
    components: {
        ElTree
    },
    data() {
        return {
            draggable: true,  // 是否允许拖拽
            editable: true,   // 是否允许编辑
            treeData: [
                {
                    id: 'chapter-1',
                    title: '第一章 标题',
                    expanded: true, // 是否展开,默认 true
                    children: [
                        {
                            id: 'section-1-1',
                            title: '第一节 标题',
                            expanded: true,
                            children: [
                                {
                                    id: 'subsection-1-1-1',
                                    title: '一、小节标题'
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    },
    methods: {
        onTreeChange(data) {
            // 拖拽排序后触发
            console.log('树结构变化:', data)
            this.treeData = data
        },
        onRegenerate(item, level, chapterIndex, sectionIndex, subsectionIndex) {
            // 重新生成事件
            console.log('重新生成:', item)
        },
        onEdit(item, level, chapterIndex, sectionIndex, subsectionIndex) {
            // 编辑事件
            console.log('编辑:', item)
        },
        onDelete(item, level, chapterIndex, sectionIndex, subsectionIndex) {
            // 删除事件
            console.log('删除:', item)
        },
        onAddRequirement(item, level, chapterIndex, sectionIndex, subsectionIndex) {
            // 添加要求事件
            console.log('添加要求:', item)
        }
    }
}
</script>

Props

参数 类型 默认值 说明
data Array [] 树形数据,格式见下方数据结构说明
draggable Boolean true 是否允许拖拽排序,为 false 时隐藏拖拽手柄并禁用拖拽功能
editable Boolean true 是否允许编辑,为 false 时隐藏所有操作按钮(重新生成、编辑、删除、添加要求)

Events

事件名 说明 回调参数
change 拖拽排序后触发 (treeData) 更新后的树形数据
regenerate 点击重新生成按钮时触发 (item, level, chapterIndex, sectionIndex, subsectionIndex)
edit 点击编辑按钮时触发 (item, level, chapterIndex, sectionIndex, subsectionIndex)
delete 点击删除按钮时触发 (item, level, chapterIndex, sectionIndex, subsectionIndex)
addRequirement 点击添加要求按钮时触发 (item, level, chapterIndex, sectionIndex, subsectionIndex)

事件参数说明

  • item: 当前操作的节点数据对象
  • level: 节点层级(1=章节, 2=节, 3=小节)
  • chapterIndex: 章节索引
  • sectionIndex: 节索引(仅 level >= 2 时有效)
  • subsectionIndex: 小节索引(仅 level === 3 时有效)

数据结构

interface TreeNode {
    id?: string | number;        // 节点唯一标识(可选)
    title: string;                // 节点标题
    expanded?: boolean;            // 是否展开,默认 true
    children?: TreeNode[];        // 子节点数组
}

// 示例数据
const treeData: TreeNode[] = [
    {
        id: 'chapter-1',
        title: '第一章 标题',
        expanded: true,
        children: [
            {
                id: 'section-1-1',
                title: '第一节 标题',
                expanded: true,
                children: [
                    {
                        id: 'subsection-1-1-1',
                        title: '一、小节标题'
                    }
                ]
            }
        ]
    }
]

使用说明

拖拽排序

  1. 拖拽手柄:每个节点左侧都有拖拽手柄(⋮⋮),长按并拖动即可开始拖拽
  2. 拖拽限制
    • 章节只能与章节交换位置
    • 节只能在本章下的节之间交换位置
    • 小节只能在本节下的小节之间交换位置
  3. 拖拽反馈:拖拽时会显示蓝色指示线,表示目标位置
  4. 禁用拖拽:设置 draggable="false" 可禁用拖拽功能,此时拖拽手柄会隐藏

折叠展开

  • 点击章节或节的展开/折叠图标(▼/▶)可以切换展开状态
  • 小节不支持折叠(没有子节点)

操作按钮

  • 重新生成:仅章节和节显示,用于重新生成内容
  • 编辑:所有节点都显示,用于编辑标题
  • 删除:所有节点都显示,用于删除节点
  • 添加要求:仅章节和节显示,用于添加要求
  • 禁用编辑:设置 editable="false" 可隐藏所有操作按钮,此时仅保留展开/折叠功能

权限控制

组件支持通过 draggableeditable 属性来控制功能权限:

<!-- 只读模式:禁止拖拽和编辑 -->
<el-tree 
    :data="treeData"
    :draggable="false"
    :editable="false"
></el-tree>

<!-- 仅查看模式:允许拖拽但不允许编辑 -->
<el-tree 
    :data="treeData"
    :draggable="true"
    :editable="false"
></el-tree>

<!-- 编辑模式:允许拖拽和编辑(默认) -->
<el-tree 
    :data="treeData"
    :draggable="true"
    :editable="true"
></el-tree>

样式定制

组件使用 scoped 样式,如需定制样式,可以通过以下方式:

  1. 深度选择器(Vue 2):

    <style>
    ::v-deep .el-tree .tree-node {
    /* 自定义样式 */
    }
    </style>
  2. 深度选择器(Vue 3):

    <style>
    :deep(.el-tree .tree-node) {
    /* 自定义样式 */
    }
    </style>

响应式设计

组件已针对不同屏幕尺寸进行优化:

  • 默认样式:适用于桌面端和较大屏幕
  • ≤750px:中等屏幕优化(平板、大屏手机)
  • ≤600px:小屏幕优化(手机)

注意事项

  1. 数据更新:拖拽排序后,组件会触发 change 事件,需要手动更新数据源
  2. 节点 ID:建议为每个节点设置唯一的 id,否则会使用索引作为 key
  3. 触摸区域:所有可点击元素的最小触摸区域为 44rpx,符合移动端标准
  4. 拖拽阈值:移动超过 10px 才会触发拖拽,避免误触
  5. 权限控制draggableeditable 属性可以动态切换,组件会实时响应变化

浏览器兼容性

  • 支持所有现代浏览器
  • 移动端浏览器完美支持
  • uni-app 全平台支持(H5、小程序、App)

更新日志

详见 CHANGELOG.md

许可证

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。