【zTree】节点添加不同操作按钮,点击后生成弹窗

zTree api 文档:https://www.treejs.cn/v3/api.php

1. 初始化树的配置项

const initZtreeSetting = () => {const setting = {view: {addHoverDom: addHoverDom, // 显示用户自定义控件selectedMulti: false,// 是否允许同时选中多个节点,默认为trueshowIcon: true,//是否显示节点的图标,默认为true},data: {simpleData: {// 使用用简单数据模式enable: true,idKey: 'id',pIdKey: 'parentId',rootPId: 0,},},callback: {onClick: handleNodeClick,// 节点被点击的回调函数beforeClick: handleNodeBeforeClick,//节点被点击前的回调函数,设置节点是否可以点击},};return setting;
};

2. 自定义操作按钮

在这里插入图片描述

const addHoverDom = (treeId, treeNode) => {let addStr = null;const add = `<span class='button add' id='btn_add_${treeNode.tId}' title='添加文件' οnfοcus='this.blur();'></span>`;const addSm = `<span class='button addSm' id='btn_addSm_${treeNode.tId}' title='添加节点' οnfοcus='this.blur();'></span>`;const edit = `<span class='button edit' id='btn_edit_${treeNode.tId}' title='编辑' οnfοcus='this.blur();'></span>`;const del = `<span class='button remove' id='btn_remove_${treeNode.tId}' title='删除' οnfοcus='this.blur();'></span>`;if (treeNode.id === '自定义') {// 自定义addStr = addSm; // 添加节点} else if (treeNode.code === 'custom') {// 自定义下的分类节点(二层)if (treeNode.pid === '自定义') {addStr = add + edit;if (_.isEmpty(treeNode.children)) {addStr += del; // 分类下子节点时,可删除该分类}} else {// 三层addStr = edit + del;}if (addStr) {const _id = `#${treeNode.tId}_span`;tippy(_id, {content: addStr,// 提示的内容trigger: 'mouseenter click',// 触发方式placement: 'right',// 出现位置interactive: true,// 是否可以交互theme: 'material',// 主题onMount: function () {// 挂载后执行$(`#btn_edit_${treeNode.tId}`)?.off('click')?.on('click', (e) => {editNode(treeId, treeNode);e.stopPropagation();});$(`#btn_add_${treeNode.tId}`)?.off('click')?.on('click', (e) => {addNode(treeId, treeNode);e.stopPropagation();});$(`#btn_addSm_${treeNode.tId}`)?.off('click')?.on('click', (e) => {saveSmNode('add', treeId, treeNode);e.stopPropagation();});$(`#btn_remove_${treeNode.tId}`)?.off('click')?.on('click', (e) => {removeNode(treeId, treeNode);e.stopPropagation();});},});}
};

tippy api文档:https://atomiks.github.io/tippyjs/v6/all-props

3. 按钮绑定事件

// 添加、编辑节点(分类)
async function saveSmNode(type: 'add' | 'mod', treeId, treeNode) {const title = type === 'add' ? '新增节点' : '编辑节点';let { value } = await ElMessageBox.prompt(title, '', {confirmButtonText: '确认',cancelButtonText:'取消',inputPattern: /\S+/,// 输入框校验规则inputPlaceholder: type === 'add' ? '请输入节点名称' : null,// 占位符inputErrorMessage: '节点名不能为空!',// 校验不通过的信息inputValue: type === 'add' ? null : treeNode.name,// 输入框默认值});try {//case1: 在该节点下新增节点if (type === 'add') {const res = await $.ajax({url: `${window.__ctx}/report/module/addNode`,type: 'POST',dataType: 'json',data: {parentId:treeNode.id,name: value,// 获取到输入框的值},});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');const zTreeObj = $.fn.zTree.getZTreeObj(treeId);zTreeObj.addNodes(treeNode , res?.object);// 更新树节点的显示//case2:对该节点进行编辑} else {const res = await $.ajax({url: `${window.__ctx}/report/module/rename`,type: 'POST',dataType: 'json',data: {id: treeNode.id,reName: value,},});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');const zTreeObj = $.fn.zTree.getZTreeObj(treeId);treeNode.name = value;zTreeObj.updateNode(treeNode);}} catch (error) {if (error === 'cancel') return;ElMessage.error(error?.message ||'提交失败');console.log(`addSmNode - error`, error);}
}// 删除
async function removeNode(treeId, treeNode) {try {const modId = treeNode.id;await ElMessageBox.confirm('是否要删除该节点?', '提示', {confirmButtonText: '确认',cancelButtonText:'取消',type: 'warning',});const res = await $.ajax({url: `${window.__ctx}/report/module/delete/${modId}`,type: 'GET',dataType: 'json',});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');$.fn.zTree.getZTreeObj(treeId).removeNode(treeNode);//移除该节点} catch (error) {if (error === 'cancel') return;ElMessage.error(error?.message || '提交失败');console.log(`removeNode - error`, error);}
}
// 添加文件
function addNode(treeId, treeNode) {...
}
// 编辑文件
function editNode(treeId, treeNode) {...
}

4. 接口请求数据, 初始化zTree

async function initZtree() {const setting = initZtreeSetting ();try {isTreeLoading.value = true;const res = await $.ajax({url: `${window.__ctx}/report/tree`,type: 'POST',dataType: 'json',});if (!res?.result) return;const treeObj = $.fn.zTree.init($('#treeId'), setting, res?.object);if (treeObj.getNodes().length >= 1) {treeObj.expandNode(treeObj.getNodes()[0], true);// 展开第一个节点}} catch (err) {console.log(`[log] - initZtree- err`, err);} finally {isTreeLoading.value = false;}
}

5. 全部代码

<template><div v-loading="isTreeLoading"><ul class="ztree" id="treeId"></ul></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const isTreeLoading = ref(false);// 初始化树的配置项
const initZtreeSetting = () => {const setting = {view: {addHoverDom: addHoverDom, // 显示用户自定义控件selectedMulti: false,// 是否允许同时选中多个节点,默认为trueshowIcon: true,//是否显示节点的图标,默认为true},data: {simpleData: {// 使用用简单数据模式enable: true,idKey: 'id',pIdKey: 'parentId',rootPId: 0,},},callback: {onClick: handleNodeClick,// 节点被点击的回调函数beforeClick: handleNodeBeforeClick,//节点被点击前的回调函数,设置节点是否可以点击},};return setting;
};
// 节点前点击事件
const handleNodeBeforeClick = (treeId, treeNode, clickFlag) => {return treeNode.reportType !== 'Node';// 返回 false,无法点击
};
// 节点点击事件
const handleNodeClick = (event, treeId, treeNode) => {console.log(`treeNode->`, treeNode);
};
// 初始化树
async function initZtree() {const setting = initZtreeSetting ();try {isTreeLoading.value = true;const res = await $.ajax({url: `${window.__ctx}/report/tree`,type: 'POST',dataType: 'json',});if (!res?.result) return;const treeObj = $.fn.zTree.init($('#treeId'), setting, res?.object);if (treeObj.getNodes().length >= 1) {treeObj.expandNode(treeObj.getNodes()[0], true);// 展开第一个节点}} catch (err) {console.log(`[log] - initZtree- err`, err);} finally {isTreeLoading.value = false;}
}
onMounted(() => {initZtree();
});//自定义操作按钮
const addHoverDom = (treeId, treeNode) => {let addStr = null;const add = `<span class='button add' id='btn_add_${treeNode.tId}' title='添加文件' οnfοcus='this.blur();'></span>`;const addSm = `<span class='button addSm' id='btn_addSm_${treeNode.tId}' title='添加节点' οnfοcus='this.blur();'></span>`;const edit = `<span class='button edit' id='btn_edit_${treeNode.tId}' title='编辑' οnfοcus='this.blur();'></span>`;const del = `<span class='button remove' id='btn_remove_${treeNode.tId}' title='删除' οnfοcus='this.blur();'></span>`;if (treeNode.id === '自定义') {// 自定义addStr = addSm; // 添加节点} else if (treeNode.code === 'custom') {// 自定义下的分类节点(二层)if (treeNode.pid === '自定义') {addStr = add + edit;if (_.isEmpty(treeNode.children)) {addStr += del; // 分类下子节点时,可删除该分类}} else {// 三层addStr = edit + del;}if (addStr) {const _id = `#${treeNode.tId}_span`;tippy(_id, {content: addStr,// 提示的内容trigger: 'mouseenter click',// 触发方式placement: 'right',// 出现位置interactive: true,// 是否可以交互theme: 'material',// 主题onMount: function () {// 挂载后执行$(`#btn_edit_${treeNode.tId}`)?.off('click')?.on('click', (e) => {editNode(treeId, treeNode);e.stopPropagation();});$(`#btn_add_${treeNode.tId}`)?.off('click')?.on('click', (e) => {addNode(treeId, treeNode);e.stopPropagation();});$(`#btn_addSm_${treeNode.tId}`)?.off('click')?.on('click', (e) => {saveSmNode('add', treeId, treeNode);e.stopPropagation();});$(`#btn_remove_${treeNode.tId}`)?.off('click')?.on('click', (e) => {removeNode(treeId, treeNode);e.stopPropagation();});},});}
};// 添加、编辑节点(分类)
async function saveSmNode(type: 'add' | 'mod', treeId, treeNode) {const title = type === 'add' ? '新增节点' : '编辑节点';let { value } = await ElMessageBox.prompt(title, '', {confirmButtonText: '确认',cancelButtonText:'取消',inputPattern: /\S+/,// 输入框校验规则inputPlaceholder: type === 'add' ? '请输入节点名称' : null,// 占位符inputErrorMessage: '节点名不能为空!',// 校验不通过的信息inputValue: type === 'add' ? null : treeNode.name,// 输入框默认值});try {//case1: 在该节点下新增节点if (type === 'add') {const res = await $.ajax({url: `${window.__ctx}/report/module/addNode`,type: 'POST',dataType: 'json',data: {parentId:treeNode.id,name: value,// 获取到输入框的值},});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');const zTreeObj = $.fn.zTree.getZTreeObj(treeId);zTreeObj.addNodes(treeNode , res?.object);// 更新树节点的显示//case2:对该节点进行编辑} else {const res = await $.ajax({url: `${window.__ctx}/report/module/rename`,type: 'POST',dataType: 'json',data: {id: treeNode.id,reName: value,},});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');const zTreeObj = $.fn.zTree.getZTreeObj(treeId);treeNode.name = value;zTreeObj.updateNode(treeNode);}} catch (error) {if (error === 'cancel') return;ElMessage.error(error?.message ||'提交失败');console.log(`addSmNode - error`, error);}
}// 删除
async function removeNode(treeId, treeNode) {try {const modId = treeNode.id;await ElMessageBox.confirm('是否要删除该节点?', '提示', {confirmButtonText: '确认',cancelButtonText:'取消',type: 'warning',});const res = await $.ajax({url: `${window.__ctx}/report/module/delete/${modId}`,type: 'GET',dataType: 'json',});if (!res.result) throw new Error(res?.message);ElMessage.success(res?.message || '提交成功');$.fn.zTree.getZTreeObj(treeId).removeNode(treeNode);//移除该节点} catch (error) {if (error === 'cancel') return;ElMessage.error(error?.message || '提交失败');console.log(`removeNode - error`, error);}
}
// 添加文件
function addNode(treeId, treeNode) {...
}
// 编辑文件
function editNode(treeId, treeNode) {...
}</script >

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/175678.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++的拷贝构造函数

目录 拷贝构造函数一、为什么用拷贝构造二、拷贝构造函数1、概念2、特征1. 拷贝构造函数是构造函数的一个重载形式。2. 拷贝构造函数的参数3. 若未显式定义&#xff0c;编译器会生成默认的拷贝构造函数。4. 拷贝构造函数典型调用场景 拷贝构造函数 一、为什么用拷贝构造 日期…

C++设计模式_18_State 状态模式

State和Memento被归为“状态变化”模式。 文章目录 1. “状态变化”模式1.1 典型模式 2. 动机 (Motivation)3. 代码演示State 状态模式3.1 常规方式3.2 State 状态模式 4. 模式定义5. 结构( Structure )6. 要点总结7. 其他参考 1. “状态变化”模式 在组件构建过程中&#xf…

Redis——哨兵模式与Zookeeper选举的异同点

摘要 当我们使用主从复制出现的问题&#xff1a;手动故障转移&#xff1a;写能力和存储能力受限&#xff1a;主从复制 -master 宕机故障处理。 主从切换技术的方法是&#xff1a;当主服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服务器&#xff0c;这就需要人工干…

军工工厂安全生产视频AI识别技术方案

一、需求分析 在国家政策、技术创新和企业发展需求转变等多个维度的共同驱动和协同下&#xff0c;特别是工业互联网作为“新基建”的提出&#xff0c;都在推动工业制造朝着数字化、网络化、智能化方向发展。军工装备制造行业承担着国民经济和国防建设的重要使命&#xff0c;构…

【uniapp】uview1.x使用upload上传图片

和2.x不同的是&#xff0c;要用 action 来配置后端上传图片的接口地址&#xff1b; 再来一些配置项的命名有所不同&#xff0c;一般1.x的命名用 -&#xff0c;2.x的命名使用小驼峰&#xff1b; 1.x 的上传会自带删除时的提示框&#xff0c;2.x 没有&#xff1b; 重要的几个配置…

银河集团香港优才计划95分获批案例展示!看看是如何申请的?

银河集团香港优才计划95分获批案例展示&#xff01;看看是如何申请的&#xff1f; 今天来分享一则银河集团香港优才计划获批案例&#xff01;客户本科学历非名校、从事业务支援及人力资源行业&#xff0c;优才打分95分&#xff0c;这个条件可能在很多人的印象里&#xff0c;会觉…

网课 - 网页视频-倍速播放-快进-拖动进度条-增大音量 - 火狐Firefox浏览器

本文使用的浏览器为火狐Firefox浏览器。 用浏览器播放视频&#xff0c;比如看网课、看在线电影电视剧时&#xff0c;经常能遇到的情况与解决方案&#xff1a; 音量太小&#xff0c;即使调整到100%还是不够响亮 这时可以安装插件“600% Sound Volume”, 安装之后可在原来音量的…

“2024杭州智慧城市展“汇集全球领先的智慧城市解决方案和前沿技术

2024杭州智慧城市展览会&#xff0c;将于2024年4月份在杭州国际博览中心盛大召开。此次展览会以智慧城市为主题&#xff0c;涵盖了智慧城市、信息安全、数据中心与通信、人工智能、公共安全、会议广播视讯、智慧社区与智能家居、智慧停车等八个模块&#xff0c;旨在推动互联网、…

Echats-自定义图表2

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-cmn-Hans"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

《C和指针》笔记35:结构体

本文整理一下结构体的相关知识&#xff0c;记录是为了更好地加深理解。 1. 结构体声明 下面两个声明语句&#xff1a; struct {int a;char b;float c; } x;struct {int a;char b;float c; } y[20], *z;这两个声明被编译器当作两种截然不同的类型&#xff0c;即使它们的成员列…

批量拍摄剪辑短视频,这几个实用又简单的拍摄技巧可以收藏学习

现在越来越多的朋友都当起了视频博主&#xff0c;自己来拍短视频&#xff0c;但说来简单&#xff0c;到了拍摄的时候&#xff0c;却有些无从下手&#xff0c;直接拿起手机就拍吗&#xff1f;是不是太平淡了&#xff1f;可自己又不会专业的拍摄技巧啊~ 今天来分享4个简单的拍摄…

Guava-RateLimiter详解

简介&#xff1a; 常用的限流算法有漏桶算法和令牌桶算法&#xff0c;guava的RateLimiter使用的是令牌桶算法&#xff0c;也就是以固定的频率向桶中放入令牌&#xff0c;例如一秒钟10枚令牌&#xff0c;实际业务在每次响应请求之前都从桶中获取令牌&#xff0c;只有取到令牌的请…

Apache ActiveMQ RCE漏洞复现(CNVD-2023-69477)

0x01 产品简介 ActiveMQ是一个开源的消息代理和集成模式服务器&#xff0c;它支持Java消息服务(JMS) API。它是Apache Software Foundation下的一个项目&#xff0c;用于实现消息中间件&#xff0c;帮助不同的应用程序或系统之间进行通信。 0x02 漏洞概述 Apache ActiveMQ 中存…

计算机视觉 计算机视觉识别是什么?

计算机视觉识别&#xff08;Computer Vision Recognition&#xff09;是计算机科学和人工智能领域中的一个重要分支&#xff0c;它致力于使计算机系统能够模拟和理解人类视觉的过程&#xff0c;从而能够自动识别、分析和理解图像或视频中的内容。这一领域的发展旨在让计算机具备…

系列三十五、Spring AOP失效原因以及解决方式

一、Spring AOP失效原因 &#xff08;1&#xff09;内部调用不会触发AOP&#xff1b; &#xff08;2&#xff09;方法是private修饰的&#xff0c;AOP会失效&#xff1b; 解决方法&#xff1a;改成public &#xff08;3&#xff09;目标类没有配置为bean&#xf…

数据结构——线性表①(顺序表)

一、线性表定义 线性表是一种数据结构&#xff0c;它是由n个具有相同数据类型的数据元素a1,a2,…,an组成的有限序列。 其中&#xff0c;除第一个元素a1外&#xff0c;每一个元素有且只有一个直接前驱元素&#xff0c;除了最后一个元素an外&#xff0c;每一个元素有且只有一个…

云原生-AWS EC2使用、安全性及国内厂商对比

目录 什么是EC2启动一个EC2实例连接一个实例控制台ssh Security groups规则默认安全组与自定义安全组 安全性操作系统安全密钥泄漏部署应用安全元数据造成SSRF漏洞出现时敏感信息泄漏网络设置错误 厂商对比参考 本文通过实操&#xff0c;介绍了EC2的基本使用&#xff0c;并在功…

关于ABB 机器人多任务的建立

关于ABB 机器人多任务的建立.需要实时监控某一区域&#xff0c;或者某一信号&#xff0c;或者计件到达某一数量机器人自动停止报警&#xff0c;显示到示教器上&#xff0c;多任务可以实现&#xff0c;类似发那科机器人后台逻辑指令 当软件选项漏选或者少选可以选择修改选项&…

近期面试小结

作者&#xff1a;究极逮虾户 最近面试了不少的公司&#xff0c;行情整体来说还是非常差的&#xff0c;如果没有必要不建议大家裸辞&#xff0c;另外就不总结面试的题目了。这次打算着重从项目经验上来给大家讨论下&#xff0c;我觉得这部分可能才是面试中得分比重比较大的部分&…

C的缺陷和陷阱读书笔记

词法陷阱 1、if语句的特殊用法 1、if(x>max) maxx;2、if(x>max?x;max) //条件表达式&#xff0c;是执行第二个&#xff0c;否执行第三个3、if(x>max); //条件成立后执行——空语句4、if((fopen(arg v[i],0))>0) //open函数执行&#xff0c;成功返回后面的0&a…