16.左侧导航菜单制作

左侧导航菜单制作

1. 修改路由,方便查看页面

index.ts

import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router";
import Layout from '@/layout/Index.vue'

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: 'home',
        component: Layout
    }
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

export default router

2. 官网

https://element-plus.org/zh-CN/component/menu.html

3. 在Layout中新建Menu.vue

3.1代码如下

<template>
  <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
    <el-radio-button :value="false">expand</el-radio-button>
    <el-radio-button :value="true">collapse</el-radio-button>
  </el-radio-group>
  <el-menu
    default-active="2"
    class="el-menu-vertical-demo"
    :collapse="isCollapse"
    @open="handleOpen"
    @close="handleClose"
  >
    <el-sub-menu index="1">
      <template #title>
        <el-icon><location /></el-icon>
        <span>Navigator One</span>
      </template>
      <el-menu-item-group>
        <template #title><span>Group One</span></template>
        <el-menu-item index="1-1">item one</el-menu-item>
        <el-menu-item index="1-2">item two</el-menu-item>
      </el-menu-item-group>
      <el-menu-item-group title="Group Two">
        <el-menu-item index="1-3">item three</el-menu-item>
      </el-menu-item-group>
      <el-sub-menu index="1-4">
        <template #title><span>item four</span></template>
        <el-menu-item index="1-4-1">item one</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-menu-item index="2">
      <el-icon><icon-menu /></el-icon>
      <template #title>Navigator Two</template>
    </el-menu-item>
    <el-menu-item index="3" disabled>
      <el-icon><document /></el-icon>
      <template #title>Navigator Three</template>
    </el-menu-item>
    <el-menu-item index="4">
      <el-icon><setting /></el-icon>
      <template #title>Navigator Four</template>
    </el-menu-item>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import {
  Document,
  Menu as IconMenu,
  Location,
  Setting,
} from '@element-plus/icons-vue'

const isCollapse = ref(true)
const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
</script>

<style scoped lang="scss">
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
</style>

3.2 效果图

在这里插入图片描述

3.3 修改样式

<template>
  <el-menu
    default-active="2"
    class="el-menu-vertical-demo"
    :collapse="isCollapse"
    @open="handleOpen"
    @close="handleClose"
    background-color="#0a2542"
  >

    <!-- 隐藏展开按钮 -->
    <el-radio-group v-model="isCollapse" style="margin-bottom: 20px;margin-left: 9px;">
      <el-radio-button :value="false" v-show="isCollapse" >|||</el-radio-button>
      <el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button>
    </el-radio-group>
    <el-sub-menu index="1">
      <template #title>
        <el-icon><location /></el-icon>
        <span>Navigator One</span>
      </template>
      <el-menu-item-group>
        <template #title><span>Group One</span></template>
        <el-menu-item index="1-1">item one</el-menu-item>
        <el-menu-item index="1-2">item two</el-menu-item>
      </el-menu-item-group>
      <el-menu-item-group title="Group Two">
        <el-menu-item index="1-3">item three</el-menu-item>
      </el-menu-item-group>
      <el-sub-menu index="1-4">
        <template #title><span>item four</span></template>
        <el-menu-item index="1-4-1">item one</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-menu-item index="2">
      <el-icon><icon-menu /></el-icon>
      <template #title>Navigator Two</template>
    </el-menu-item>
    <el-menu-item index="3" disabled>
      <el-icon><document /></el-icon>
      <template #title>Navigator Three</template>
    </el-menu-item>
    <el-menu-item index="4">
      <el-icon><setting /></el-icon>
      <template #title>Navigator Four</template>
    </el-menu-item>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import {
  Document,
  Menu as IconMenu,
  Location,
  Setting,
} from '@element-plus/icons-vue'

//只允许展开一个子菜单
// const uniqueOpened = ref(true)
const isCollapse = ref(true)
const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
</script>

<style scoped lang="scss">
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 230px;
  min-height: 400px;
}
.el-menu {
  border-right: none;
}

//主菜单颜色
:deep(.el-sub-menu .el-sub-menu__title){
	 color: #f5f4f4 !important;
}

/*子菜单文字颜色*/
:deep(.el-menu .el-menu-item){
	color: #e1e5ea;
}
/* 菜单点中文字的颜色 */

:deep(.el-menu-item.is-active){
	color: #f07810 !important;
}
/* 当前打开菜单的所有子菜单颜色 */

:deep(.is-opened .el-menu-item){
	background-color: #082343 !important;
}
/* 鼠标移动菜单的颜色 */

:deep(.el-menu-item:hover){
	background-color: #001528 !important;
}


</style>

3.4 效果图

在这里插入图片描述

在这里插入图片描述

4. 在Layout中新建MenuItem.vue

4.1 代码如下

<template>
    <template v-for="menu in menuList" :key="menu.path">
        <!-- 判断是否有子菜单 -->
        <el-sub-menu v-if="menu.children && menu.children.length > 0" :index="menu.path">
            <template #title>
                <el-icon>
                    <!-- 动态组件 图标传入 -->
                    <component :is="menu.meta.icon"></component>
                </el-icon>
                <span>{{ menu.meta.title }}</span>
            </template>
            <!-- 递归渲染子菜单 -->
            <menu-item :menuList="menu.children"></menu-item>
        </el-sub-menu>
        <el-menu-item v-else :index="menu.path">
            <el-icon>
                <component :is="menu.meta.icon"></component>
            </el-icon>
            <template #title>
                {{ menu.meta.title }}
            </template>
        </el-menu-item>
    </template>
</template>

<script setup lang="ts">
// 接收父组件传递的menuList数据
defineProps(['menuList'])
</script>

<style scoped lang="less">

</style>

知识点补充

component是vue内置组件,主要作用为动态渲染组件,基本用法如下:

官网:动态组件 & 异步组件 | Vue.js (vueframework.com)

<!-- 动态组件由 vm 实例的 `componentName` property 控制 -->
<component :is="componentName"></component>

4.2 Menu.vue修改

<template>
  <!-- router是否启用 vue-router 模式。 
    启用该模式会在激活导航时以 index 作为 path 
    进行路由跳转 使用 default-active 来设置加载时的激活项。 -->
  <el-menu
    default-active="/dashboard"
    class="el-menu-vertical-demo"
    :collapse="isCollapse"
    router
    unique-opened
    @open="handleOpen"
    @close="handleClose"
    background-color="#0a2542"
  >

    <!-- 隐藏展开按钮 -->
    <el-radio-group v-model="isCollapse" style="margin-bottom: 20px;margin-left: 9px;">
      <el-radio-button :value="false" v-show="isCollapse" >|||</el-radio-button>
      <el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button>
    </el-radio-group>
    <!-- 父组件传递数据 -->
    <MenuItem :menuList="menuList"></MenuItem>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref,reactive } from 'vue'
import MenuItem from './MenuItem.vue';


//菜单数据
let menuList = reactive([
  {
    path: "/dashboard",
    component: "Layout",
    name: "dashboard",
    meta: {
      title: "首页",
      icon: "HomeFilled",
      roles: ["sys:dashboard"],
    },
  },
  {
    path: "/system",
    component: "Layout",
    name: "system",
    meta: {
      title: "系统管理",
      icon: "Setting",
      roles: ["sys:manage"],
    },
    children: [
      {
        path: "/adminUser",
        component: "/system/AdminUser",
        name: "adminUser",
        meta: {
          title: "管理员管理",
          icon: "UserFilled",
          roles: ["sys:adminUser"],
        },
      },
      {
        path: "/userList",
        component: "/system/UserList",
        name: "userList",
        meta: {
          title: "用户管理",
          icon: "Wallet",
          roles: ["sys:userList"],
        },
      },
      {
        path: "/menuList",
        component: "/system/MenuList",
        name: "menuList",
        meta: {
          title: "菜单管理",
          icon: "Menu",
          roles: ["sys:menu"],
        },
      },
    ],
  },
  {
    path: "/goodsRoot",
    component: "Layout",
    name: "goodsRoot",
    meta: {
      title: "商品管理",
      icon: "Histogram",
      roles: ["sys:goodsRoot"],
    },
    children: [
      {
        path: "/goodsType",
        component: "/goods/GoodsType",
        name: "goodsType",
        meta: {
          title: "商品分类",
          icon: "UserFilled",
          roles: ["sys:goodsType"],
        },
      },
      {
        path: "/unusedList",
        component: "/goods/UnusedList",
        name: "unusedList",
        meta: {
          title: "闲置商品",
          icon: "Wallet",
          roles: ["sys:unusedList"],
        },
      },
      {
        path: "/buyList",
        component: "/goods/BuyList",
        name: "buyList",
        meta: {
          title: "求购商品",
          icon: "Wallet",
          roles: ["sys:buyList"],
        },
      },
    ],
  },
  {
    path: "/order",
    component: "Layout",
    name: "order",
    meta: {
      title: "订单管理",
      icon: "Tickets",
      roles: ["sys:order"],
    },
    children: [
      {
        path: "/unusedOrder",
        component: "/order/UnusedOrder",
        name: "unusedOrder",
        meta: {
          title: "闲置订单",
          icon: "UserFilled",
          roles: ["sys:unusedOrder"],
        },
      },
      {
        path: "/buyOrder",
        component: "/order/BuyOrder",
        name: "buyOrder",
        meta: {
          title: "求购订单",
          icon: "Wallet",
          roles: ["sys:buyOrder"],
        },
      },
    ],
  },
  {
    path: "/comment",
    component: "Layout",
    name: "comment",
    meta: {
      title: "评论管理",
      icon: "Briefcase",
      roles: ["sys:comment"],
    },
    children: [
      {
        path: "/commentList",
        component: "/comment/CommentList",
        name: "commentList",
        meta: {
          title: "评论列表",
          icon: "UserFilled",
          roles: ["sys:commentList"],
        },
      },
    ],
  },
]);

//只允许展开一个子菜单
// const uniqueOpened = ref(true)
const isCollapse = ref(true)
const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
</script>

<style scoped lang="scss">
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 230px;
  min-height: 400px;
}
.el-menu {
  border-right: none;
}



//主菜单颜色
:deep(.el-sub-menu .el-sub-menu__title){
	 color: #f5f4f4 !important;
}

/*子菜单文字颜色*/
:deep(.el-menu .el-menu-item){
	color: #e1e5ea;
}
/* 菜单点中文字的颜色 */

:deep(.el-menu-item.is-active){
	color: #f07810 !important;
}
/* 当前打开菜单的所有子菜单颜色 */

:deep(.is-opened .el-menu-item){
	background-color: #082343 !important;
}
/* 鼠标移动菜单的颜色 */

:deep(.el-menu-item:hover){
	background-color: #001528 !important;
}


</style>

4.3 在index.vue中引入

<template>
    <el-container class="mycontainer">
        <el-aside width="230px" class="asside">
            <Menu></Menu>
        </el-aside>
        <el-container>
            <el-header class="header">Header</el-header>
            <el-main class="mymain">Main</el-main>
        </el-container>
    </el-container>
</template>

<script setup lang="ts">
import Menu from "./Menu.vue"
</script>

<style scoped lang="scss">
.mycontainer{
    height: 100%;
    .asside{
        background-color: #0a2542;
        // 使宽度自适应
        width: auto;
    }
    .header{
        background-color: rgb(164, 194, 255);
    }
    .mymain{
        background-color: rgb(242, 187, 136);
    }
}
</style>

5. 最终效果

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录大三上学期大数据课程设计:基于Hadoop和Spark的中文手写数字实时识别系统

我整理好了两个百度网盘链接&#xff0c;一个是模型文档和数据&#xff0c;一个是镜像&#xff0c;下载、导入虚拟机即可运行。 github地址&#xff1a;Li-Jihong/big-data: 用来记录大三上学期大数据课程设计&#xff1a;基于Hadoop和Spark的中文手写数字实时识别系统 (githu…

服务器如何远程桌面连接不上,服务器远程桌面连接不上解决办法

服务器远程桌面连接不上&#xff0c;是IT运维中常见的挑战之一。针对这一问题&#xff0c;专业的解决方法通常涉及以下几个方面的排查与操作&#xff1a; 首先&#xff0c;我们需要检查网络连接是否正常。远程桌面连接依赖于稳定的网络连接&#xff0c;因此&#xff0c;确认服务…

Rocky Linux 9.4 部署Zabbix 7.0

文章目录 Zabbix基本概念zabbix介绍zabbix特性zabbix结构 安装Zabbix主机名配置配置Zabbix-Server(1)禁用EPEL提供的Zabbix软件包(2)安装Zabbix Server、Web前端、Agent(3)创建初始数据库(4)Zabbix server配置数据库(5)为Zabbix前端配置PHP(6)启动Zabbix server和agent进程(7)放…

【JS重点知识05】正则表达式

目录 一&#xff1a;正则表达式简介 1 什么是正则表达式 2 正则表达式作用 二&#xff1a;语法格式&#xff1a; 1 定义正则表达式 2 检索、判断是否匹配 &#xff08;1&#xff09;test()方法 &#xff08;2&#xff09;exec()方法 三&#xff1a;元字符 普通字符&a…

【C++课程学习】:类和对象(拷贝构造和运算符重载)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 ✍拷贝构造&#xff1a; &#x1f349;特点一&#xff1a; &#x1f349;特点二&#xff1a; &…

消息中间件比较:Redis,Kafka和RabbitMQ

对微服务使用异步通信时&#xff0c;通常使用消息代理。代理确保不同微服务之间的通信可靠且稳定&#xff0c;消息在系统内得到管理和监控&#xff0c;并且消息不会丢失。您可以从几个消息代理中进行选择&#xff0c;它们的规模和数据功能各不相同。这篇博文将比较三种最受欢迎…

基于深度图像的无监督目标跟踪

概要 大致的步骤 深度图像获取:通过深度传感器(例如ToF相机、双目相机等)获取场景的深度图像。深度图转scanscan转pointcloud点云聚类卡尔曼滤波预测匈牙利算法匹配目标ID更新深度图转scan 参考这篇博客 scan转pointcloud

科技云报道:“元年”之后,生成式AI将走向何方?

科技云报道原创。 近两年&#xff0c;以大模型为代表的生成式AI技术&#xff0c;成为引爆数字原生最重要的技术奇点&#xff0c;人们见证了各类文生应用的进展速度。Gartner预测&#xff0c;到2026年&#xff0c;超过80%的企业将使用生成式AI的API或模型&#xff0c;或在生产环…

C++基础(二)

选择结构 选择结构是用来控制程序流程&#xff0c;使得程序可以根据不同的条件执行不同的代码块。 if语句 简单结构 if (表达式) { // 表达式为真时执行的语句。 } else { // 表达式为假时执行的语句。 } #include <iostream> #include <string>using namespace s…

卫星通讯传输电力运维巡检EasyCVR视频汇聚平台智能监控方案

随着科技的快速发展&#xff0c;视频监控技术已广泛应用于各个领域。而卫星通讯作为一种高效、稳定的通信方式&#xff0c;为视频监控系统的远程传输提供了有力支持。 一、方案背景 随着电力行业的快速发展&#xff0c;电力运维巡检工作变得愈发重要。传统的巡检方式往往受到…

知识图谱的应用---新零售

文章目录 新零售知识图谱构建过程典型应用 新零售 新零售&#xff0c;即个人、企业以互联网为依托&#xff0c;通过运用大数据、人工智能等先进技术手段并运用心理学知识&#xff0c;对商品的生产、流通与销售过程进行升级改造&#xff0c;进而重塑业态结构与生态圈&#xff0c…

镜舟科技携手中通快运,入选 2024 爱分析·数据库应用实践报告

典型案例&#xff1a;中通快运重构数据中心&#xff0c;满足业务多种复杂分析需求 中通快运成立于2016年&#xff0c;是中通品牌旗下快运企业&#xff0c;聚焦数智物流新趋势&#xff0c; 提供面向企业及个人客户的全链路一站式物流服务。目前中通快运全国揽派件网点有21000 余…

MySQL存储引擎详述:InnoDB为何胜出?

MySQL作为当前最流行的开源关系型数据库之一,其强大的功能和良好的性能使其广泛应用于各种规模的应用系统中。其中,存储引擎的设计理念是MySQL数据库灵活高效的关键所在。 一、什么是存储引擎 存储引擎是MySQL架构的重要组成部分,负责MySQL中数据的存储和提供了视图,存储过程等…

大疆智图_空三二维重建成果传输

一、软件环境 1.1 所需软件 1、 大疆智图&#xff1a;点击下载&#xff1b;   2、 ArcGIS Pro 3.1.5&#xff1a;点击下载&#xff0c;建议使用IDM或Aria2等多线程下载器&#xff1b;   3、 IDM下载器&#xff1a;点击下载&#xff0c;或自行搜索&#xff1b;   4、 Fas…

初出茅庐的小李博客之CJSON库解析心知天气数据

心知天气数据JSON格式介绍 JSON格式介绍http://t.csdnimg.cn/pJX1n 下面代码是利用CJSON库进行数据解析 解析代码 #include <stdio.h> #include <string.h> #include "cJSON.h" // 假设你的CJSON库头文件路径是正确的int main(void) {// 提供的JSON…

LLM基础介绍

文章目录 一、语言模型1、概念2、预训练语言模型3、NLP4、benchmark1&#xff09;概念2&#xff09;GLUE 5、TPU6、语料 二、神经网络1、概念2、训练神经网络3、案例&#xff1a;word2vec3、RNN&#xff08;循环神经网络&#xff09;4、GRU5、LSTM&#xff08;长短时记忆网络&a…

SLT简介【简单介绍SLT】

SLT简介 在c的学习当中STL的学习是一个很重要的一环&#xff0c;但是STL又是一个庞大的章节&#xff0c;因此这里我们先简单介绍一下STL&#xff0c;有助于后面我们对STL的学习&#xff0c;这里就是做一个简单的介绍&#xff0c;并无干货。 1.什么是STL STL(standard templa…

Python自动化测试框架pytest的详解安装与运行

1. pytest的介绍 pytest是一个非常成熟的全功能的python测试工具&#xff0c;它主要有以下特征&#xff1a; 简单灵活&#xff0c;容易上手&#xff1b; 支持简单的单元测试和复杂的功能测试 显示详细的断言失败信息 能自动识别测试模块和测试功能 有测试会话、测试模块、…

【全开源】多平台租房系统源码(Fastadmin+ThinkPHP+Uniapp)

&#x1f3e0;多平台租房系统&#xff1a;一站式租房新体验&#x1f50d; &#x1f310;一、引言&#xff1a;租房市场的变革 在快节奏的现代生活中&#xff0c;租房已成为许多人解决居住问题的首选。然而&#xff0c;传统的租房方式往往繁琐且效率低下。随着互联网的飞速发展…

1996-2023年各省农林牧渔总产值数据(无缺失)

1996-2023年各省农林牧渔总产值数据&#xff08;无缺失&#xff09; 1、 时间&#xff1a;1996-2023年 2、 来源&#xff1a;国家统计局、统计年鉴 3、 指标&#xff1a;农林牧渔总产值 4、 范围&#xff1a;31省 5、 缺失情况&#xff1a;无缺失 6、 指标解释&…