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>
相关推荐
jktantan1 小时前
(二)Vue 3 的 attrs 不是响应式:el-form 扩展属性同步的三种方案
前端·javascript·vue.js·element-plus
echome8882 小时前
JavaScript async/await 错误处理:别让 Promise 静默失败
开发语言·前端·javascript·promise
#麻辣小龙虾#3 小时前
网页布局css中flex+margin的组合布局技巧
开发语言·前端·javascript
Hello.Reader3 小时前
Three.js / Cesium 卡顿怎么办?把三维渲染搬到 GPU 服务器
服务器·开发语言·javascript
chi11303 小时前
【无标题】
前端·javascript·python
萝卜兔0084 小时前
PIKACHU_UnsafeFileUpload
javascript·php
Highcharts.js4 小时前
Highcharts 集成到 React 或 Vue 项目中时,如何高效地使用 TypeScript技巧?
vue.js·人工智能·react.js·typescript·前端框架·highcharts
Java后端的Ai之路13 小时前
CAS并发控制-从CPU指令到企业级乐观锁
vue.js·人工智能·python·cas·乐观锁
程序员大阳16 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
香芋芋圆20 小时前
iD-editor 详解|OSM官方在线编辑器,基于D3.js的轻量地图编辑器
开发语言·javascript·编辑器