效果展示:
注:本文使用的是vue2和element-ui,如有使用vue3的可以查看element-plus文档修改部分内容。
实现步骤:
展示树形文件夹@node-contextmenu=“floderOption”:element-ui定义的右键点击事件
data为element-ui中自带的json格式的数据
<el-tree :data="data" draggable node-key="id" @node-contextmenu="floderOption"><span class="custom-tree-node" slot-scope="{ node, data }"><i class="el-icon-folder" style="color: #DFBA49; margin-right: 5px;"></i><span style="font-size: 15px;">{{node.label }}</span></span></el-tree>
一些需要定义的数据:
右键点击事件获取当前鼠标位置,点击的节点node等信息
floderOption函数
// 文件夹右键时触发的事件floderOption(e, data, n, t) {this.optionCardShow = false this.optionCardX = e.x // 让右键菜单出现在鼠标右键的位置this.optionCardY = e.y - 110this.optionData = datathis.node = n // 将当前节点保存this.tree = tthis.optionCardShow = true // 展示右键菜单},
右键菜单代码
‘z-index’: 9999 是为了保证菜单不被覆盖
<div :style="{'z-index': 9999, position: 'fixed',left: optionCardX + 'px', top: optionCardY + 'px', width: '100px', background: 'white','box-shadow': '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)'}" v-show="optionCardShow" id="option-button-group"><el-button @click="append" class="option-card-button">新建文件夹</el-button><el-button @click="remove" class="option-card-button">删除文件夹</el-button><el-button @click="rename" class="option-card-button">重命名</el-button></div>
点击除菜单以外其他区域,菜单隐藏
OptionCardClose 定义在菜单最高层父组件上
OptionCardClose(event) {var currentCli = document.getElementById("option-button-group");if (currentCli) {if (!currentCli.contains(event.target)) {//点击到了id为option-button-group以外的区域,就隐藏菜单this.optionCardShow = false;}}},
当data一开始为空时,需要建立根目录,方法如下:
此方法需要新建一个按钮并添加事件来调用。
// 新建一个根目录nweRoot(){this.$prompt('请输入文件名', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',inputPattern: /^\S{1,10}$/,inputErrorMessage: '文件名长度在1到10之间'}).then(({value}) => {createFolder(this.qlId, 0, value).then(res=>{// console.log(res)if(res.code == 200) {this.showFolderList()this.$message({type: 'success',message: '文件夹新建成功!'});}})}).catch(() => {this.$message({type: 'info',message: '取消输入'});});},
新建一个子文件夹
append() {this.optionCardShow = falsethis.$prompt('请输入文件名', '提示', {// 弹出框用于输入文件名confirmButtonText: '确定',cancelButtonText: '取消',inputPattern: /^\S{1,10}$/,inputErrorMessage: '文件名长度在1到10之间'}).then(({value}) => {if (this.node.level >= 3) {this.$message.error("最多只支持三级!")return false;}const newChild = {// 新建一个子节点id: id++, // 要在script中定义一个全局变量idlabel: value,children: []};if (!this.optionData.children) {// 如果当前节点没有子节点,那就新建一个空的子节点数组,用来存放新建子文件夹this.$set(this.optionData, 'children', []);}this.optionData.children.push(newChild); // 插入//同时展开节点if (!this.node.expanded) {this.node.expanded = true}this.$message({type: 'success',message: '文件夹新建成功!'});}).catch(() => {this.$message({type: 'info',message: '取消输入'});});},
删除文件夹
remove() {this.optionCardShow = falsethis.$confirm('此操作将永久删除该文件夹, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {const parent = this.node.parent;const children = parent.data.children || parent.data;const index = children.findIndex(d => d.id === this.data.id);children.splice(index, 1);this.$message({type: 'success',message: '删除成功!'});}).catch(() => {this.$message({type: 'info',message: '已取消删除'});});},
修改文件夹名字
rename(){console.log(this.node)this.optionCardShow = falsethis.$prompt('请输入文件名', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',inputPlaceholder: this.node.data.label,inputPattern: /^\S{1,10}$/,inputErrorMessage: '文件名长度在1到10之间'}).then(({value}) => {this.node.data.label = valuethis.$message({type: 'success',message: '文件夹已重命名!'});}).catch(() => {this.$message({type: 'info',message: '取消输入'});});},
Style样式
// 文件夹卡片.folder-box {height: 100%;}// 右键菜单按钮.option-card-button {width: 100%;margin-left: 0;font-size: 10px;border-radius: 0;}