element-ui 树形控件el-tree右键自定义菜单实现节点增删改

效果展示:

element-ui 树形控件el-tree右键自定义菜单实现节点增删改_第1张图片
注:本文使用的是vue2和element-ui,如有使用vue3的可以查看element-plus文档修改部分内容。

实现步骤:

  1. 展示树形文件夹
    @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>

一些需要定义的数据:
element-ui 树形控件el-tree右键自定义菜单实现节点增删改_第2张图片

  1. 右键点击事件获取当前鼠标位置,点击的节点node等信息
    floderOption函数
// 文件夹右键时触发的事件
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>
  1. 点击除菜单以外其他区域,菜单隐藏
    OptionCardClose 定义在菜单最高层父组件上
OptionCardClose(event) {
	var currentCli = document.getElementById("option-button-group");
	if (currentCli) {
		if (!currentCli.contains(event.target)) { //点击到了id为option-button-group以外的区域,就隐藏菜单
			this.optionCardShow = false;
		}
	}
},
  1. 当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: '取消输入'
		});
	});
},
  1. 新建一个子文件夹
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: '取消输入'
		});
	});
},
  1. 删除文件夹
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: '已取消删除'
		});
	});
},
  1. 修改文件夹名字
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: '取消输入'
		});
	});
},
  1. Style样式
// 文件夹卡片
.folder-box {
	height: 100%;
}

// 右键菜单按钮
.option-card-button {
	width: 100%;
	margin-left: 0;
	font-size: 10px;
	border-radius: 0;
}

你可能感兴趣的:(vue+springboot,ui,vue.js,elementui)