当前位置: 首页 > news >正文

vue3写一个无限树形菜单,递归组件

原本使用element plus的el-tree,可是他的UI不匹配,狠难改成自己想要的,所以只能自己去写一个,做法:使用递归组件

效果

在这里插入图片描述

组件代码itemDir.vue

// itemDir.vue<template><div><ul v-for="node in lists" :key="node.id" class="menu-item"><li :class="{ active: node.id === activeId }" @click="selectNode(node)"><span class="item-item-text" :style="{ paddingLeft: depth * 20 + 'px' }">{{ node.name }}</span><el-icon v-if="node.childs && node.childs.length" class="arrow"><ArrowDown v-if="isExpanded(node)" /><ArrowRight v-else /></el-icon></li><el-collapse-transition><template v-if="isExpanded(node) && node.childs && node.childs.length"><ItemDir v-model="activeId" :lists="node.childs" :depth="depth + 1" /></template></el-collapse-transition></ul></div>
</template><script setup>
import { ArrowRight, ArrowDown } from '@element-plus/icons-vue'
import { ref, watch } from 'vue'const props = defineProps({modelValue: {type: Number,default: undefined},lists: {type: Array,default: () => []},depth: {type: Number,default: 0}
})
const emits = defineEmits(['update:modelValue'])const activeId = ref(props.modelValue)
const expandedNodes = ref([])watch(() => props.modelValue,newValue => {activeId.value = newValue}
)watch(activeId, newValue => {emits('update:modelValue', newValue)
})const isExpanded = node => expandedNodes.value.some(n => n.id === node.id)const selectNode = node => {activeId.value = node.idconsole.log(node)const index = expandedNodes.value.findIndex(n => n.id === node.id)if (index === -1) {expandedNodes.value.push(node)} else {expandedNodes.value.splice(index, 1)}
}
</script><style lang="scss" scoped>
.menu-item {> li {display: flex;align-items: center;justify-content: space-between;box-sizing: border-box;height: 44px;padding-right: 12px;padding-left: 24px;color: #666666;font-weight: 400;font-size: 12px;font-family: PingFangSC, 'PingFang SC';font-style: normal;line-height: 12px;text-align: left;cursor: pointer;}.active {color: #333333;font-weight: bold;background: #f5f5f5;}
}
</style>

调用index.vue

// index.vue<template><div class="menu-list"><itemDir v-model="activeId" :lists="menus" /></div>
</template><script setup>
import { ref, onMounted, watch } from 'vue'
import itemDir from './itemDir.vue'
const activeId = ref(undefined)
const menus = ref([{"id": 187,"pid": null,"name": "地图资源库","childs": [{"id": 201,"pid": 187,"name": "电子地图底座","childs": [{"id": 225,"pid": 201,"name": "全球S-57电子海图数据","childs": null,},{"id": 226,"pid": 201,"name": "基于互联网应用的中国电子海图服务","childs": null,},{"id": 227,"pid": 201,"name": "S-57全球连续无缝背景电子海图","childs": null,}],},{"id": 202,"pid": 187,"name": "海陆图融合","childs": [{"id": 222,"pid": 202,"name": "海图","childs": null,},{"id": 223,"pid": 202,"name": "海图及陆图","childs": null,},{"id": 224,"pid": 202,"name": "海图及卫星图","childs": null,}],},{"id": 203,"pid": 187,"name": "区域边界设置","childs": [{"id": 215,"pid": 203,"name": "管辖边界标注","childs": null,},{"id": 216,"pid": 203,"name": "航道边界标注","childs": null,},{"id": 217,"pid": 203,"name": "港口边界标注","childs": null,},{"id": 218,"pid": 203,"name": "锚地边界标注","childs": null,},{"id": 219,"pid": 203,"name": "领海边界标注","childs": null,},{"id": 220,"pid": 203,"name": "经济专属区边界标注","childs": null,},{"id": 221,"pid": 203,"name": "管控区域边界标注","childs": null,}],},{"id": 204,"pid": 187,"name": "长江航道瓦片图","childs": null,},{"id": 205,"pid": 187,"name": "地图叠加图层","childs": [{"id": 206,"pid": 205,"name": "辖区航标数据库","childs": null,},{"id": 207,"pid": 205,"name": "辖区海区数据库","childs": null,},{"id": 208,"pid": 205,"name": "辖区时区数据库","childs": null,},{"id": 209,"pid": 205,"name": "辖区国家领海基线数据库","childs": null,},{"id": 210,"pid": 205,"name": "辖区重要海峡数据库","childs": null,},{"id": 211,"pid": 205,"name": "辖区海上贸易区数据库","childs": null,},{"id": 212,"pid": 205,"name": "辖区金融敏感区数据库","childs": null,},{"id": 213,"pid": 205,"name": "辖区主要海盗区数据库","childs": null,},{"id": 214,"pid": 205,"name": "辖区废弃污染物ECA排放控制区数据库","childs": null,}],}],},
])
</script>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 利用AI进行社交媒体创作及管理的14种简单方法
  • AOSP:在rom中打入一个脚本
  • ARM----时钟
  • 【全网最全】2024年数学建模国赛B题31页完整建模过程+25页成品论文+matlab/python代码等(后续会更新
  • 【数据库】MySQL表的Updata(更新)和Delete(删除)操作
  • 【Hot100】LeetCode—394. 字符串解码
  • Post-Training有多重要?一文带你了解全部细节
  • 【MySQL00】【 杂七杂八】
  • Python 错误 TypeError 解析,实际错误实例详解 (五)
  • 强调重点元素、弱化辅助元素、去掉无关元素,工控HMI还能好不了
  • ChatGPT在论文写作领域的应用:初稿设计
  • 在前端中Proj4.js使用简单介绍
  • HarmonyOS】ArkTS学习之基于TextTimer的简易计时器的elapsedTime最小时间单位问题
  • LinuxPTP的安装与应用
  • HCIE云计算--灾备
  • JavaScript-如何实现克隆(clone)函数
  • 《Java编程思想》读书笔记-对象导论
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • CSS相对定位
  • Effective Java 笔记(一)
  • ES6--对象的扩展
  • ES6核心特性
  • IDEA 插件开发入门教程
  • MySQL QA
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Sublime Text 2/3 绑定Eclipse快捷键
  • 百度地图API标注+时间轴组件
  • 关于字符编码你应该知道的事情
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端相关框架总和
  • 使用 @font-face
  • 学习HTTP相关知识笔记
  • 智能合约开发环境搭建及Hello World合约
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • #{}和${}的区别是什么 -- java面试
  • #define 用法
  • #define与typedef区别
  • #在 README.md 中生成项目目录结构
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (PADS学习)第二章:原理图绘制 第一部分
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (ZT)出版业改革:该死的死,该生的生
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (四)React组件、useState、组件样式
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (译)计算距离、方位和更多经纬度之间的点
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转) ns2/nam与nam实现相关的文件
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • . NET自动找可写目录