注:本文使用的是vue2和element-ui,如有使用vue3的可以查看element-plus文档修改部分内容。
<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>
// 文件夹右键时触发的事件
floderOption(e, data, n, t) {
this.optionCardShow = false
this.optionCardX = e.x // 让右键菜单出现在鼠标右键的位置
this.optionCardY = e.y - 110
this.optionData = data
this.node = n // 将当前节点保存
this.tree = t
this.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(event) {
var currentCli = document.getElementById("option-button-group");
if (currentCli) {
if (!currentCli.contains(event.target)) { //点击到了id为option-button-group以外的区域,就隐藏菜单
this.optionCardShow = false;
}
}
},
// 新建一个根目录
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 = false
this.$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中定义一个全局变量id
label: 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 = false
this.$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 = false
this.$prompt('请输入文件名', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPlaceholder: this.node.data.label,
inputPattern: /^\S{1,10}$/,
inputErrorMessage: '文件名长度在1到10之间'
}).then(({
value
}) => {
this.node.data.label = value
this.$message({
type: 'success',
message: '文件夹已重命名!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '取消输入'
});
});
},
// 文件夹卡片
.folder-box {
height: 100%;
}
// 右键菜单按钮
.option-card-button {
width: 100%;
margin-left: 0;
font-size: 10px;
border-radius: 0;
}