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

news2024/12/26 10:47:16

原本使用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.id
  console.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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java+Swing+sqlserver学生成绩管理系统

JavaSwingsqlserver学生成绩管理系统 一、系统介绍二、系统展示1.登陆2.课程分配3.选课管理4.学生打分--教师4.查询个人成绩--学生 三、其他1.其它系统 一、系统介绍 管理员:登陆页面、课程管理、选课管理 老师&#xff1a;给学生打分 学生&#xff1a;查询个人成绩 二、系…

景联文科技:专业图像采集服务,助力智能图像分析

景联文科技是专业数据服务公司&#xff0c;致力于为人工智能企业提供从数据采集、清洗到标注的全流程解决方案。协助客户解决AI开发过程中数据处理环节的关键问题&#xff0c;助力企业实现智能化转型。 1.多样化的图像采集服务 景联文科技提供多样化的图像采集服务&#xff0c…

7.9.17 Readiness Time Reporting Extended Capability

RTR提供了一种可选机制&#xff0c;用于描述设备或功能进入准备状态所需的时间。在指示的情况下&#xff0c;允许软件在等待此功能中公告的时间后向设备或功能发出请求&#xff0c;并且无需等待其他地方所需的&#xff08;更长&#xff09;时间。 软件允许在最早的时间发出请求…

【漏洞复现】赛蓝企业管理系统 GetJSFile 任意文件读取漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

策略模式的小记

策略模式 策略模式支付系统【场景再现】硬编码完成不同的支付策略使用策略模式&#xff0c;对比不同&#xff08;1&#xff09;支付策略接口&#xff08;2&#xff09;具体的支付策略类&#xff08;3&#xff09;上下文&#xff08;4&#xff09;客户端&#xff08;5&#xff0…

【Redis】Redis Sentinel(哨兵)系统:自动故障恢复与高可用性配置全解

目录 哨兵 (Sentinel)基本概念主从复制的问题⼈⼯恢复主节点故障哨兵⾃动恢复主节点故障 安装部署 (基于 docker)准备⼯作 以下部分是独立于这一章节的Docker安装Server版本安装CentOS安装实战经验 GUI版本安装&#xff08;以windows 11为例&#xff09;安装docker 以上部分是独…

elementUI table 给表头添加气泡显示(鼠标悬浮显示注释)

elementUI table 给表头添加气泡显示&#xff08;鼠标悬浮显示注释&#xff09; 前言&#xff1a;文档显示&#xff1a;&#xff08;使用插槽&#xff0c;我看看到底是怎么个事儿&#xff09;文档代码:修改后的效果&#xff1a;页面效果&#xff1a; 前言&#xff1a; 公司出现…

Termius for Mac/Win:高效、安全的跨平台多协议远程管理软件

Termius for Mac/Win是一款专为专业人士设计的跨平台多协议远程管理软件&#xff0c;以其强大的功能、简洁的界面和高效的操作体验&#xff0c;赢得了广泛的好评。这款软件不仅支持SSH、Telnet、SFTP等多种远程连接协议&#xff0c;还具备丰富的安全特性和便捷的管理功能&#…

免费的月考成绩发布小程序

月考成绩出炉&#xff0c;老师们便开始了一项既繁琐又耗时的工作&#xff1a;将成绩单私信给每位学生家长。需要老师们在繁忙的教学工作中抽出自己额外休息的时间&#xff0c;还要确保每位家长都能及时准确的收到自己孩子的成绩单。然而&#xff0c;随着科技的发展&#xff0c;…

歌者PPT新功能速递!

本期功能更新&#xff0c;主要围绕 PPT 大纲编辑器和 PPT 翻译功能&#xff0c;全面提升了制作效率和灵活性&#xff0c;帮助你更轻松地完成 PPT 制作&#xff01;一起来看看吧&#xff5e;&#x1f447; # 功能更新 1 PPT 大纲编辑器全面更新 &#x1f4dd; 现在&#xff0c…

StarRocks Lakehouse 快速入门——Apache Iceberg

导读&#xff1a; StarRocks Lakehouse 快速入门旨在帮助大家快速了解湖仓相关技术&#xff0c;内容涵盖关键特性介绍、独特的优势、使用场景和如何与 StarRocks 快速构建一套解决方案。最后大家也可以通过用户真实的使用场景来了解 StarRocks Lakehouse 的最佳实践&#xff01…

C++入门(03)新手常见问题集锦(一)

文章目录 1. 一闪而过使用system("pause")使用cin.get() 1. 一闪而过 .exe 在用户计算机上运行后“一闪而过”&#xff0c;因为控制台程序没有专门的用户图形界面&#xff0c;当程序执行完所有代码后就会自动关闭窗口。 使用system(“pause”) 在程序的结尾处加入…

Iceberg与SparkSQL整合DDL操作

前言 使用SparkSql操作Iceberg表之前我们得先配置好catalog&#xff0c;配置方式参考这篇博客。 创建非分区表 Spark3使用USING iceberg来创建表&#xff1a; CREATE TABLE prod.db.sample (id bigint NOT NULL COMMENT unique id,data string) USING iceberg;这里的数据类…

伦敦银ATR策略

ATR这个技术指标由J.Welles Wilder发明&#xff0c;‌主要用来衡量伦敦银的价格波动&#xff0c;它虽然‌不能直接反映银价走向及其趋势稳定性&#xff0c;但‌ATR指标价值越高&#xff0c;‌趋势改变的可能性就越高&#xff1b;‌价值越低&#xff0c;‌趋势的移动性就越弱。 …

麒麟安全加固工具,为系统打造坚固“金钟罩”!

当今数字化时代&#xff0c;系统安全的重要性不言而喻。为应对网络安全风险、满足用户高等级安全诉求&#xff0c;麒麟软件打造了满足用户高等级安全诉求的 “麒麟安全加固工具”&#xff0c;实现服务器操作系统安全配置的规范化、标准化、制度化&#xff0c;为系统安全打造坚固…

node.js、php、Java、python校园点餐与数据分析系统 校园食堂订餐系统(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

uni-app--》打造个性化壁纸预览应用平台(三)

&#x1f3d9;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名前端工程师 &#x1f304;个人主页&#xff1a;亦世凡华、 &#x1f306;系列专栏&#xff1a;uni-app &#x1f307;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

微服务注册中心都有哪些

在微服务架构中&#xff0c;注册中心扮演着至关重要的角色&#xff0c;用于服务的注册与发现。以下是一些常见的注册中心&#xff1a; Eureka&#xff1a; Eureka是Netflix开发的服务发现框架&#xff0c;后来贡献给了Spring Cloud。它主要用于AWS云&#xff0c;但也可以在其他…

【MySQL超详细安装步骤】Centos7安装MySQL8

文章目录 1.卸载2.修改yum源为阿里源2.1首先检查是否安装wget2.2 备份 yum 源文件2.3 下载阿里云yum源文件2.4 清理yum缓存 3.安装mysql源3.1 下载mysql源3.2 安装mysql源3.3 检查是否安装成功 4. 安装MySQL4.1 使用yum安装4.2 启动MySQL 5.配置防火墙5.1 开放3306端口 6.登录M…

服务器数据恢复—Raid磁盘阵列故障类型和常见故障原因

出于尽可能避免数据灾难的设计初衷&#xff0c;RAID解决了3个问题&#xff1a;容量问题、IO性能问题、存储安全(冗余)问题。从数据恢复的角度讨论RAID的存储安全问题。 常见的起到存储安全作用的RAID方案有RAID1、RAID5及其变形。基本设计思路是相似的&#xff1a;当部分数据异…