el-tree 拖拽事件隔离:实现句柄独立控制,区域分离

html 复制代码
<template>
  <el-tree
    ref="treeRef"
    class="tree-container"
    :data="treeList"
    node-key="courseContentId"
    default-expand-all
    draggable
    :expand-on-click-node="true"
    :allow-drop="allowDrop"
    :allow-drag="allowDrag"
    @node-drag-start="handleNodeDragStart"
    @node-drag-end="handleNodeDragEnd"
    @node-drop="handleNodeDrop"
  >
    <template #default="{ data }">
      <div class="drag-icon" @mousedown="handleDragHandleMouseDown">⋮⋮</div>
      {{ data.label }}
    </template>
  </el-tree>
</template>

<script setup lang="ts">
import { ref } from "vue";

const treeList = ref([
  {
    label: "Level one 1",
    children: [
      {
        label: "Level two 1-1",
        children: [
          {
            label: "Level three 1-1-1",
          },
        ],
      },
    ],
  },
  {
    label: "Level one 2",
    children: [
      {
        label: "Level two 2-1",
        children: [
          {
            label: "Level three 2-1-1",
          },
        ],
      },
      {
        label: "Level two 2-2",
        children: [
          {
            label: "Level three 2-2-1",
          },
        ],
      },
    ],
  },
  {
    label: "Level one 3",
    children: [
      {
        label: "Level two 3-1",
        children: [
          {
            label: "Level three 3-1-1",
          },
        ],
      },
      {
        label: "Level two 3-2",
        children: [
          {
            label: "Level three 3-2-1",
          },
        ],
      },
    ],
  },
]);

const isDragHandleClicked = ref(false);

const handleDragHandleMouseDown = () => {
  isDragHandleClicked.value = true;
};

const handleNodeDragEnd = () => {
  isDragHandleClicked.value = false;
};

const allowDrag = () => {
  if (!isDragHandleClicked.value) {
    return false;
  }
  return true;
};

const handleNodeDragStart = (node, event) => {
  const target = event.target;

  const dragIconElement = target.closest(".drag-icon");
  if (!dragIconElement) {
    if (event.dataTransfer) {
      event.dataTransfer.dropEffect = "none";
      event.dataTransfer.effectAllowed = "none";
    }
    isDragHandleClicked.value = false;
    return false;
  }
  return true;
};

const allowDrop = () => {
  return true;
};

const handleNodeDrop = async () => {
  isDragHandleClicked.value = false;
};
</script>

<style lang="less" scoped>
.drag-icon {
  margin-right: 10px;
}
</style>
相关推荐
计算机毕设定制辅导-无忧学长4 分钟前
《校园食堂在线订餐小程序的设计与实现》
java·vue.js·spring boot·微信小程序·uniapp·校园食堂在线订餐小程序
EatFan28 分钟前
React 项目踩坑实录:useEffect 闭包陷阱、Context 性能陷阱与 React 18 升级避坑排查手册
前端·javascript·react.js·react·react hooks·useeffect·闭包陷阱
咖啡无伴侣2 小时前
1. 别再手动改代码格式了!Vue3 项目工程化规范搭建实战
vue.js·架构
w2sfot4 小时前
【JS加密在线】jsjiami.online(让JavaScript 更安全!)
开发语言·javascript·安全
知野小兔4 小时前
Vuex和Pinia状态管理
vue.js
VX_bysjlw9855 小时前
数码设备销售网站设计与实现39138-计算机毕设原创(免费领源码+带部署教程)
java·vue.js·spring boot·mysql·tomcat·mybatis·idea
杨杰3988 小时前
我给嵌入式设备写了个 6MB 的 JavaScript 运行时(xuan)
javascript
只睡四小时9 小时前
AI 生成 PPTX:11 页课件编译出 429 个形状
javascript·python·pptx·ai生成ppt·ooxml
whi10 小时前
一个小工具,解决了一个困扰 Vue 开发者多年的类型检查难题
vue.js·typescript
shmily麻瓜小菜鸡10 小时前
Axios 中 params 与 data 的区别与原理
javascript·typescript