之前按照项目需求使用element中的tree来创建目录列表,如今记录一下。
一、项目需求
1.完整展示目录列表
2.右击节点选择重命名,删除,创建文件夹三个选项
3.拖拽文件夹,其中拖拽文件夹有以下要求:
a. 如果该文件夹内已存在上传文件,则其他文件夹不能拖拽进入该文件夹内
b.整个目录中有且仅有一个根目录,拖拽文件夹的范围只能在该根目录里面
4.重命名文件夹要求:
a.重命名完成后按enter键完成
5.删除文件夹要求:
a.如果该文件夹内已含有上传文件,则删除失败
6.创建文件夹要求:
a.如果该文件夹内已含有上传文件,则创建失败
二、思路整理
1.在mounted中向后台请求项目列表,然后存储treeData
2.鼠标右键弹出的是menu菜单选项框,对于获取点击节点的信息可以使用el-tree中的 @node-contextmenu="rightClick"
3.选择删除文件夹的时候要注意在发送请求的同时也要完成前端的“删除”动作,使用map,indexOf, slice
4.重命名中使用@keyup.enter.native来触发请求,使用focus()聚焦输入框
5.鼠标右击的时候menu的位置是随之改变的,且当鼠标位置加上menu的高度或宽度超出视频范围的时候要合适调节menu的位置。
/* 菜单定位基于鼠标点击位置 */ let height = document.documentElement.clientHeight || document.body.clientHeight if (event.clientY + 168 > height) { menu.style.left = event.clientX - 5 + 'px' menu.style.top = event.clientY - 10 - 168 + 'px' } else { menu.style.left = event.clientX + 10 + 'px' menu.style.top = event.clientY + 5 + 'px' }
6.menu的显示与隐藏,当鼠标点击其他位置的时候,menu隐藏
document.addEventListener('click', this.hide, true) document.removeEventListener('click', this.hide)
7.当文件夹命名过长的时候,出现横向滚动条
.comp-tree { margin-top: 1em; overflow-y: hidden; overflow-x: scroll; } .el-tree { min-width: 100%; display:inline-block !important; }
三、源码分析
参考:
在此基础上做的修改
<template> <div v-loading="isLoading" class="comp-tree" @click="hiddenMenu"> <el-tree ref="SlotTree" :data="treeData" :props="defaultProps" :expand-on-click-node="true" highlight-current :node-key="NODE_KEY" @node-click="handleNodeClick" @node-contextmenu="rightClick" @node-drag-start = "handleDragStart" @node-drop="handleDrop" :draggable = draggable default-expand-all > <div class="comp-tr-node" slot-scope="{ node, data }"> <!-- 编辑状态 --> <template v-if="node.isEdit"> <el-input v-model="data.menuName" autofocus size="mini" :ref="'slotTreeInput'+data.recordId" @keyup.enter.native="handleInput(node, data)"> </el-input> </template> <!-- 非编辑状态 --> <template v-else> <!-- 名称: 新增节点增加class(is-new) --> <span> <span>