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>
相关推荐
前端那点事2 小时前
Vue生命周期速查:Vue2+Vue3钩子全解析,新手也能秒懂
前端·vue.js
Aotman_3 小时前
Element UI 表格搜索高亮
前端·javascript·vue.js·ui·elementui
Dillon Dong3 小时前
【系列主题】拯救 OOM 与构建中断:Next.js 在 Docker 中的静态生成(SSG)避坑指南
开发语言·javascript·docker
han_hanker4 小时前
下拉模糊搜索多选, 编辑,详情问题
开发语言·javascript·ecmascript
yqcoder4 小时前
[特殊字符] Vue 3 中 Keep-Alive 对生命周期的影响:深度解析
前端·javascript·vue.js
jiayong234 小时前
第 33 课:任务看板视图(按状态分列)与本地持久化
开发语言·前端·javascript·学习
Yeats_Liao4 小时前
后台 Sidebar 伸缩交互(PC + 移动端)实现
前端·javascript·css·html5
MXN_小南学前端5 小时前
computed 计算属性详解:触发时机、实战场景、Vue2 与 Vue3 对比
前端·javascript·vue.js
isNotNullX5 小时前
数据大屏怎么做?数据大屏有哪四个核心环节
开发语言·前端·javascript