原生html vue3使用element plus 的树tree上移下移案例源码

上效果 

html源码

<!DOCTYPE html>
<html lang="en">
<!--
* @Name: mallSalesReports.html
* @Description:
* @Author Lani
* @date 2024-02-28 18:32:36
-->
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>商品类别</title><script src="../js/vue3.3.8/vue.global.js"></script><script src="../js/elementPlus/index.full.js"></script><link rel="stylesheet" href="../js/elementPlus/index.css"><style>.el-header {height: 88px;background-color: #fff;z-index: 2;}#main-body .el-main {padding: 0;z-index: 1;}.el-aside {display: flex;justify-content: center;align-items: center;}.el-tree .el-tree-node__content {height: 50px !important;border-top: 1px solid #aaa;}.tree {border-bottom: 1px solid #aaa;border-left: 1px solid #aaa;border-right: 1px solid #aaa;/*width: 600px;*/}.custom-tree-node1 {display: flex;flex: 1;align-items: center;justify-content: space-between;font-size: 14px;padding: 8px;height: 50px;}</style>
</head>
<body>
<div id="app" class="common-layout" v-cloak><el-affix :offset="0"><el-row :gutter="0" style="border-bottom: 0px solid #d0d0d0;margin:0 20px;padding: 15px 0;background-color: #fff;"><el-col :span="22"><div class="flex-r"><h4 class="menu-title-color fw7 fz22">商品销售报表</h4></div></el-col><el-col :span="2" style="text-align: end"><el-button type="primary" size="large" @click="handleAddTopLevelNode">新增一级目录</el-button></el-col></el-row></el-affix><el-container><el-main id="main-body"><el-treeref="menutree":allow-drop="allowDrop" :allow-drag="allowDrag":data="treeData" draggable:expand-on-click-node="false"default-expand-all node-key="id"class="tree"><template #default="{ node, data }"><div class="custom-tree-node1"><div><el-input v-if="data.isEdit" v-model="data.DICT_VALUE" maxlength="12" show-word-limit></el-input><el-text v-else="!node.isEdit">{{ data.DICT_VALUE }}</el-text></div><div style="margin-left: 40px;"><el-button type="text" size="small" v-if="data.up"@click="handleMoveUp(node, data, 'up')">上移<i class="el-icon-top"></i></el-button><el-buttontype="text" size="small" v-if="data.down"@click="handleMoveDown(node, data, 'down')">下移<i class="el-icon-bottom"></i></el-button><el-button @click="append(node,data)" type="primary" v-if="data.subNode"> 添加子级</el-button><el-button style="margin-left: 18px" @click="edit(node, data)">{{ data.operateBtnText }}</el-button><el-button style="margin-left: 18px" @click="remove(node, data)" v-if="data.delete"> 删除</el-button></div></div></template></el-tree></el-main></el-container>
</div>
</body>
<script type="module">import zhCn from "../js/elementPlus/locale/zh-cn.mjs";const {createApp, ref, reactive, watch, toRaw, toRefs, shallowRef} = Vueconst _app = createApp({setup() {const categoryInfo = reactive({maxLevel: 2,//类别层级最大2treeData: [{ //默认保留第一个节点数不能为空label: '全部商品',DICT_VALUE: '全部商品',up: false, down: true, subNode: true, delete: false, operateBtnText: '修改',id: 1,children: [{label: 'Level two 1-1',DICT_VALUE: 'Level two 1-1',id: 2,up: false, down: true, subNode: true, delete: true, operateBtnText: '修改',},],},{ //默认保留第一个节点数不能为空label: '花吃了那女孩',DICT_VALUE: '花吃了那女孩',up: false, down: true, subNode: true, delete: false, operateBtnText: '修改',id: 1,children: [{label: 'Level two 1-1',DICT_VALUE: 'Level two 1-1',id: 2,up: false, down: true, subNode: true, delete: true, operateBtnText: '修改',},],},],id: 1})const payStatus = ref('')const num = ref(20)const timer = ref(null);const clickCount = ref(0);const locale = ref('')const searchKeywords = ref('')/** 判断结点拖拽* */const allowDrop = (draggingNode, dropNode, type) => {// console.log('|--正在拖拽draggingNode,type', draggingNode, type)// console.log('|--dropNode', dropNode)if (type == 'inner') return false //只能同级拖拽if (draggingNode.level > categoryInfo.maxLevel) return falsereturn true//允许拖拽}const allowDrag = (draggingNode) => {return !draggingNode.data.label.includes('Level three 3-1-1')}const toast = (message, type = 'warning', fn = null) => {ElementPlus.ElMessage({message,type, fn})}/** 插入:$refs.menutree.insertBefore* 删除:$refs.menutree.remove* */const handleMoveUp = (node) => {  // 上移的原理就是现在选中节点上方复制一个一模一样的节点,然后删掉原来那个const {$treeNodeId, ...newData} = node.dataconsole.log('|--选中结点', node.data, vm.$refs.menutree, $treeNodeId, newData, node.previousSibling.data.$treeNodeId)if (vm.$refs.menutree) vm.$refs.menutree.insertBefore(newData, node.previousSibling)// if (vm.$refs.menutree) vm.$refs.menutree.insertBefore(newData, node.previousSibling.data.$treeNodeId)if (vm.$refs.menutree) vm.$refs.menutree.remove(node)saveCategoryRequest()}const handleMoveDown = (node) => {  // 下移的原理就是现在选中节点下方复制一个一模一样的节点,然后删掉原来那个const {$treeNodeId, ...newData} = node.dataif (vm.$refs.menutree) vm.$refs.menutree.insertAfter(newData, node.nextSibling)// if (vm.$refs.menutree) vm.$refs.menutree.insertAfter(newData, node.nextSibling.data.$treeNodeId)if (vm.$refs.menutree) vm.$refs.menutree.remove(node)saveCategoryRequest()}/** node: 当前节点,* data: 当前节点* */const append = (node, data) => {//给当前节点,添加一个子节点console.log('|--添加', node, data)if (node.level >= categoryInfo.maxLevel) {toast(`级别最大只能为${categoryInfo.maxLevel}`)return}categoryInfo.id = categoryInfo.id + 1const newChild = {label: '二级类别 ',id: categoryInfo.id,children: [],up: data.children.length > 0 ? true : false,down: false,subNode: false,delete: true,isEdit: true,operateBtnText: '保存',/*API字段*/"DICT_SEQ": 0,DICT_VALUE: '二级类别 ',}if (!data.children) {data.children = []}data.children.push(newChild)data.items = JSON.parse(JSON.stringify(data.children))if (data.children.length > 1) {data.children[data.children.length - 2].down = true}}const handleAddTopLevelNode = () => { //添加一级类别categoryInfo.id = categoryInfo.id + 1let newTopLevelNode = {id: categoryInfo.id,label: '一级类别 ',up: true, down: false, subNode: true, delete: true, isEdit: true, operateBtnText: '保存',children: [],items: [],"DICT_SEQ": 0,DICT_VALUE: '一级类别 ',}categoryInfo.treeData.push(newTopLevelNode)if (categoryInfo.treeData.length > 1) {categoryInfo.treeData[categoryInfo.treeData.length - 2].down = true}}/** isAPI: true:用于请求掊口,删除不用字段, false 用于ui渲染增加一些字段* */const refreshTree = (data, isAPI = false) => {for (let i = 0; i < data.length; i++) {// data[i].id = data[i].DICT_SEQif (isAPI && data[i]) { // 上传修改try {delete data[i].labeldelete data[i].updelete data[i].downdelete data[i].subNodedelete data[i].deletedelete data[i].isEditdelete data[i].operateBtnTextdata[i].items = JSON.parse(JSON.stringify(data[i].children))  //同步itemsif ((!data[i].children) || (data[i].children.length <= 0)) continuedata[i].items = refreshTree(data[i].items, isAPI)delete data[i].children} catch (e) {}continue}//渲染uidata[i].label = data[i].DICT_VALUEdata[i].up = (i != 0)data[i].down = (i != (data.length - 1))data[i].subNode = truedata[i].delete = truedata[i].isEdit = falsecategoryInfo.id = categoryInfo.id + 1data[i].id = categoryInfo.iddata[i].operateBtnText = '修改'data[i].children = []if ((!data[i].items) || (data[i].items.length <= 0)) continuedata[i].children = refreshTree(data[i].items, isAPI)// console.log(data[i].children)}return data}const saveCategoryRequest = async () => {console.log('|-http 请求-')toast('Http请求')}return {...toRefs(categoryInfo),num,locale, searchKeywords,clickCount, timer,headerCellStyle: {borderTop: '2px solid #d0d0d0', background: '#f5f5f5', color: '#333', fontWeight: 500},// 方法allowDrag, allowDrop,toast, append, handleMoveDown, handleMoveUp,//移除节点remove: (node, data) => {console.log("|--del", node, data, node.data.$treeNodeId)const {$treeNodeId} = node.dataconsole.log('|--', $treeNodeId, vm.$refs.menutree)// returnif (categoryInfo.treeData.length <= 1) {toast('至少保留一个结点')return;}if (!vm.$refs.menutree) returnconsole.log('|--remove')// vm.$refs.menutree.remove($treeNodeId)vm.$refs.menutree.remove(node) //OK// vm.$refs.menutree.remove(data)saveCategoryRequest()/* const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex((d) => d.id === data.id);children.splice(index, 1);*/}, //移除节点edit: (node, data) => {let btnText = '保存'if (data.isEdit) {saveCategoryRequest()btnText = '修改'}data.isEdit = !data.isEditdata.operateBtnText = btnText},handleAddTopLevelNode,payStatusItemSelectedEvent: (item, index) => {payStatus.value = item.item},refreshTree, saveCategoryRequest,menuMoveF: (node, data, type) => { //上移,下移 结点,指针console.log('|--node', node)// 将变动之前的node备份let copyNode = {...node};console.log(copyNode)copyNode.previousSibling = {...node.previousSibling};copyNode.nextSibling = {...node.nextSibling};console.log('|--copyNode 复制节点--|', copyNode)let nodeData = {};if (node.previousSibling) { //上移vm.$refs.menutree.remove(node.data);// 删除原先的node// 拿到copy的node   // nodeData = CircularJSON.parse(nodeData = copyNode// 复制该node到指定位置(参数:1. 要增加的节点的 data 2. 要增加的节点的后一个节点的 data、key 或者 node)/*  vm.$refs.menutree.insertBefore(nodeData.data,nodeData.previousSibling.data);  */vm.$refs.menutree.insertBefore(nodeData.data,nodeData.previousSibling.data);window.sessionStorage.removeItem("menuNode");} else {toast("该菜单已经是当前层最上级");}returnif (type === "up") {  // 上移if (node.previousSibling) {vm.$refs.menutree.remove(node.data);// 删除原先的node// 拿到copy的node   // nodeData = CircularJSON.parse(nodeData = copyNode// 复制该node到指定位置(参数:1. 要增加的节点的 data 2. 要增加的节点的后一个节点的 data、key 或者 node)vm.$refs.menutree.insertBefore(nodeData.data,nodeData.previousSibling.data);window.sessionStorage.removeItem("menuNode");} else {toast("该菜单已经是当前层最上级");}} else {  // 下移if (node.nextSibling) {vm.$refs.menutree.remove(node.data);nodeData = CircularJSON.parse(window.sessionStorage.getItem("menuNode"));// 参数:1. 要增加的节点的 data 2. 要增加的节点的前一个节点的 data、key 或者 nodevm.$refs.menutree.insertAfter(nodeData.data,nodeData.nextSibling.data);window.sessionStorage.removeItem("menuNode");} else {toast("该菜单已经是当前层最下级");}}}}},async mounted() {},})_app.use(ElementPlus, {locale: zhCn})const vm = _app.mount('#app')
</script></html>

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

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

相关文章

[uni-app] uni.createAnimation动画在APP端无效问题记录

文章目录 uni.createAnimation动画描述动画代码templatejs部分 问题原因改进方案template js部分改动git 改进截图 uni.createAnimation 动画描述 实现一个以左上角为锚点,以Z轴做平面抬起及落下的动画效果 动画代码 template <image v-if"showHot(item.cname)&quo…

wayland(xdg_wm_base) + egl + opengles 使用 Assimp 加载带光照信息的材质文件Mtl 实现光照贴图的最简实例(十七)

文章目录 前言一、3d 立方体 model 属性相关文件1. cube1.obj2. cube1.Mtl3. 纹理图片 cordeBouee4.jpg二、实现光照贴图的效果1. 依赖库和头文件1.1 assimp1.2 stb_image.h2. egl_wayland_obj_cube1.cpp3. Matrix.h 和 Matrix.cpp4. xdg-shell-client-protocol.h 和 xdg-shell…

GitHub gpg体验

文档 实践 生成新 GPG 密钥 gpg --full-generate-key查看本地GPG列表 gpg --list-keys关联GPG公钥与Github账户 gpg --armor --export {key_id}GPG私钥对Git commit进行签名 git config --local user.signingkey {key_id} # git config --global user.signingkey {key_id} git…

ASPICE规范之系统追溯矩阵

系统追溯矩阵的需求来自 ISO26262 举例在描述系统追溯矩阵时&#xff1a;客户需求->系统需求&#xff1b;系统需求->客户需求&#xff1b;系统需求->软件需求&#xff1b;系统需求->硬件需求

(简单成功)Mac:命令设置别名

案例&#xff1a;给"ls -l"命令&#xff0c;设置别名通过”ll“快速访问 1、在项目根目录底下查看有无.bash_profile文件&#xff0c;注意这个是个隐藏文件&#xff0c;需要使用ls -a命令查看&#xff1a; 没有.bash_profile新建一个文件&#xff0c; 在最后添加一行…

.NET 异步编程(异步方法、异步委托、CancellationToken、WhenAll、yield)

文章目录 异步方法异步委托async方法缺点CancellationTokenWhenAllyield 异步方法 “异步方法”&#xff1a;用async关键字修饰的方法 异步方法的返回值一般是Task<T>&#xff0c;T是真正的返回值类型&#xff0c;Task<int>。惯例&#xff1a;异步方法名字以 Asy…

Java城管智慧执法管理系统源码带APP

目录 一、系统概述 二、系统开发环境 三、功能模块 四、应用价值 1、提升案件办理效率 2、提升监管效能 3、提升行政执法水平 4、推进行政执法创新 一、系统概述 智慧城管系统是一个基于现代信息技术手段的综合管理平台&#xff0c;旨在通过强化信息获取自动化、监督管…

UE5拷贝复制快捷键修改Ctrl+w

UE5默认修改了原来的Ctrl w的快捷键方式&#xff0c;改成Ctrl D 非常不习惯 其实可以在编辑器中进行修改快捷键的 位置在 Editor Preferences &#xff0c;搜索 Duplicate&#xff0c; 在其中的command selection中&#xff0c;修改 按键为Ctrl w 如图所示&#xff1b; …

js指定浏览器打开页面

文章目录 前言Js错误示例Node.js实现小结 前言 今天在过需求的时候&#xff0c;碰到一个问题&#xff0c;A系统要将B系统的页面嵌入进来并进行展示。但是A系统只支持google浏览器&#xff0c;而B系统里面有几个菜单是必须运行在IE浏览器中的&#xff0c;因此该怎么实现呢&…

MT6825编码器在STM32中的使用

文章目录 1、PWM 绝对值位置读取功能1.1 DataSheet说明1.2 硬件支持1.3 Cubemax配置及使用1.4 项目代码实现1.5 效果验证1.6 注意事项 2、SPI 绝对值位置读取功能2.2 硬件支持2.3 Cubemax配置及使用2.4 项目代码实现 1、PWM 绝对值位置读取功能 1.1 DataSheet说明 1.2 硬件支持…

计算机二级(Python)真题讲解每日一题:《方菱形》

描述‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬ 请写代码替换横线&#xff0…

uniapp 云开发省钱之调整函数执行内存大小

我这个5块钱一个月的服务空间配置&#xff1a; 现在还只有少量的用户和自己测试之用&#xff0c;目前消耗的情况&#xff1a; 云函数的使用量还是挺高的&#xff0c;目前还是正好能覆盖一个月的使用量&#xff0c;等用户量上来肯定是不行的&#xff0c;所以得想想办法压榨一下云…

2024年度最佳大型语言模型(LLMs)汇总

大型语言模型(LLMs)是人工智能文本处理的主要类型&#xff0c;也现在最流行的人工智能应用形态。ChatGPT是迄今为止最著名的使用LLM的工具&#xff0c;它由OpenAI的GPT模型的特别调整版本提供动力。但还有许多其他聊天机器人和文本生成器&#xff0c;包括从Google Bard和Anthro…

Basic RNN

文章目录 回顾RNNRNN CellRNNCell的使用RNN的使用 RNN例子使用RNN Cell实现使用RNN实现 嵌入层 Embedding独热向量的缺点Embedding LSTMGRU(门控循环单元)练习 回顾 DNN&#xff08;全连接&#xff09;&#xff1a;和CNN相比&#xff0c;拥有巨大的参数量&#xff0c;CNN权重共…

MySQL与金蝶云星空对接集成SELECT语句连通销售订单新增(销售订单集成测试)

MySQL与金蝶云星空对接集成SELECT语句连通销售订单新增(销售订单集成测试) ​​ ​​ 数据源系统:MySQL MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQLAB公司开发&#xff0c;属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在WEB应用方…

【mybatis】objectwrapper解读

简介 在 MyBatis 中&#xff0c;ObjectWrapper 是一个关键的接口&#xff0c;用于详细封装了对象的属性信息。ObjectWrapper 主要用于内部操作&#xff0c;它抽象了对象的属性操作&#xff0c;使得 MyBatis 能够统一处理原生类型、Bean 对象以及 Map 集合等。 类图展示 主要功…

架构扩展性

架构扩展性&#xff1a;应用扩展 数据扩展 组织扩展 流程扩展 核心方法论–扩展立方体&#xff1a; x轴&#xff1a;无脑克隆 y轴&#xff1a;功能分割z轴&#xff1a;客户分割扩展立方体在应用扩展的应用&#xff1a; x轴&#xff1a;横向克隆 对于无状态的应用&#xff0c;多…

苹果意将Gemini引入iPhone;英伟达发布新AI GPU;Grok正式开源

苹果正在谈判将 Gemini 引入 iPhone Mark Gurman 报道&#xff0c;苹果正在谈判将 Google 的生成式 AI 大模型 Gemini 引入 iPhone。 知情人士透露&#xff0c;两家公司正在积极谈判&#xff0c;让苹果获得 Gemini 授权&#xff0c;为今年 iPhone 软件的一些新功能提供动力。苹…

2024年Jira全面解析:从 Jira 的概念到优缺点、最新政策

Jira是澳大利亚的Atlassian公司开发的一款项目管理软件&#xff0c;名字来源于日文中“哥斯拉”的称呼“Gojira”。Jira不仅可以追踪缺陷和问题&#xff0c;还能管理项目。很多企业还将JIRA用于一些特殊的场景&#xff0c;比如作为仓库自动化工具、管理文档流程、优化费用等等。…

Python之Web开发中级教程----ubuntu安装MySQL

Python之Web开发中级教程----ubuntu安装MySQL 进入/opt目录 cd /opt 更新软件源 sudo apt-get upgrade sudo apt-get update 3、安装Mysql server sudo apt-get install mysql-server 4、启动Mysql service mysql start 5、确认Mysql的状态 service mysql status 6、安全设…