首页
/ Vue.Draggable高级应用:树形结构拖拽实现

Vue.Draggable高级应用:树形结构拖拽实现

2026-02-05 05:10:08作者:丁柯新Fawn

你是否在开发中遇到过需要实现层级菜单拖拽排序的需求?是否尝试过让用户通过拖拽快速调整组织架构图?本文将通过Vue.Draggable实现树形结构拖拽的完整方案,解决嵌套列表排序、父子节点联动、跨层级移动等核心痛点。读完本文你将掌握:递归组件设计、拖拽作用域控制、动态数据同步三大关键技能。

核心原理与准备工作

树形结构拖拽的本质是递归组件+拖拽作用域隔离。Vue.Draggable基于SortableJS实现,通过group属性控制拖拽组,利用递归组件渲染多层级结构。

首先确保项目中已正确安装依赖:

npm install vuedraggable --save

核心文件结构:

基础树形拖拽实现

1. 递归组件设计

创建可嵌套的拖拽组件example/components/infra/nested.vue,关键代码:

<template>
  <draggable class="dragArea" tag="ul" :list="tasks" :group="{ name: 'g1' }">
    <li v-for="el in tasks" :key="el.name">
      <p>{{ el.name }}</p>
      <nested-draggable :tasks="el.tasks" />
    </li>
  </draggable>
</template>

<script>
import draggable from "@/vuedraggable";
export default {
  props: { tasks: { type: Array, required: true } },
  components: { draggable },
  name: "nested-draggable"
};
</script>

2. 数据结构定义

在父组件example/components/nested-example.vue中定义树形数据:

data() {
  return {
    list: [
      {
        name: "task 1",
        tasks: [{ name: "task 2", tasks: [] }]
      },
      {
        name: "task 3",
        tasks: [{ name: "task 4", tasks: [] }]
      }
    ]
  };
}

3. 组件引用

<template>
  <div class="row">
    <div class="col-8">
      <h3>Nested draggable</h3>
      <nested-draggable :tasks="list" />
    </div>
    <rawDisplayer :value="list" title="当前数据结构" />
  </div>
</template>

高级特性实现

跨层级拖拽控制

通过group属性控制拖拽范围,实现同一父节点内拖拽:

<!-- 仅允许同组内拖拽 -->
<draggable :group="{ name: 'g1', pull: 'clone', put: false }">

拖拽样式定制

为拖拽区域添加视觉反馈:

.dragArea {
  min-height: 50px;
  outline: 1px dashed #ccc;
  padding: 10px;
  margin: 5px 0;
}
.dragArea li {
  background: #fff;
  border: 1px solid #ddd;
  padding: 8px;
  margin: 4px 0;
  cursor: move;
}

数据同步与边界处理

添加拖拽事件监听,处理跨层级移动时的数据同步:

<draggable 
  @end="onDragEnd"
  :list="tasks">
  <!-- 节点内容 -->
</draggable>

<script>
export default {
  methods: {
    onDragEnd(evt) {
      // 处理拖拽结束后的数据修正
      console.log("拖动结束", evt.oldIndex, evt.newIndex);
    }
  }
};
</script>

常见问题解决方案

1. 多层级拖拽混乱

问题:深层级节点拖拽后数据结构异常
方案:使用:clone属性自定义复制逻辑,参考example/components/clone.vue

2. 性能优化

当节点数量超过50个时,启用filter属性过滤不可拖拽元素,减少DOM操作:

<draggable :filter=".nodrag" :list="tasks">
  <li v-for="item in tasks">
    <span :class="{nodrag: item.disabled}">{{item.name}}</span>
  </li>
</draggable>

3. 与第三方组件集成

结合Element UI表格实现树形表格拖拽,参考example/components/table-example.vue

完整示例与扩展

嵌套带v-model示例

查看example/components/nested-with-vmodel.vue,实现双向绑定的树形拖拽:

<template>
  <nested-draggable v-model="treeData" />
</template>

拖拽动画效果

添加过渡动画提升用户体验,参考example/components/transition-example.vue

<draggable :list="tasks">
  <transition-group name="flip-list">
    <li v-for="item in tasks" :key="item.id">
      {{ item.name }}
    </li>
  </transition-group>
</draggable>

<style>
.flip-list-move {
  transition: transform 0.5s;
}
</style>

总结与后续学习

通过递归组件和Vue.Draggable的group属性组合,我们实现了灵活的树形结构拖拽功能。核心要点:

  • 递归组件渲染多层级结构
  • group属性控制拖拽作用域
  • 拖拽事件处理数据同步

进阶学习资源:

掌握这些技术后,你可以轻松实现如组织架构图、多级菜单、文件管理器等复杂交互场景。尝试扩展节点折叠/展开功能,打造更完善的树形拖拽组件吧!

登录后查看全文
热门项目推荐

项目优选

收起
docsdocs
暂无描述
Markdown
827
5.49 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
494
518
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
786
1.58 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
803
1.14 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
973
2.29 K
kernelkernel
deepin linux kernel
C
32
16
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
482
312
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.02 K
769
cannbot-skillscannbot-skills
CANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体,本仓库为其提供可复用的 Skills 模块。
Markdown
1.26 K
811
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
648
287