16.左侧导航菜单制作

news2024/11/20 19:27:25

左侧导航菜单制作

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. 最终效果

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

【牛客面试必刷TOP101】Day31.BM60 括号生成和BM61 矩阵最长递增路径

文章目录 前言一、BM60 括号生成题目描述题目解析二、BM61 矩阵最长递增路径题目描述题目解析总结 前言 一、BM60 括号生成 题目描述 描述&#xff1a; 给出n对括号&#xff0c;请编写一个函数来生成所有的由n对括号组成的合法组合。 例如&#xff0c;给出n3&#xff0c;解集为…

Python办公MySQL(一):安装MySQL以及Navicat可视化工具(附送Navicat到期解决方法)

目录 专栏导读1、下载 MySQL Community Server2、安装3、安装Navicat4、连接刚刚安装的MySQL5、创建一个数据库方法1方法2 6、创建一张表方法1&#xff1a;准备一个test文件方法2&#xff1a; Navicat到期解决总结 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Pytho…

玩转ChatGPT:最全学术论文提示词分享【下】

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 本篇文章&#xff0c;是系列文章「最全学术论文提示词」的完结篇。前两篇的内容请到文末链接处跳转&#x1f447;&#x1f3fb; 11.提交和发布 prompt 1&#xff1a;根据[期刊/会议]指…

【GreenHills】关于GHS加密狗license激活成功后打开软件提示无可用授权

【更多软件使用问题请点击亿道电子官方网站】 1、 问题场景 用于解决在使用加密狗license去激活旧版本的GHS的时候&#xff0c;激活页面显示激活成功&#xff0c;但是&#xff0c;打开软件显示无可用license&#xff08;如图2-1&#xff09;&#xff0c;重新激活现象还是一样的…

SpringBoot高手之路jdk动态代理

文章目录 JDK动态代理基于jdk的动态代理Aop底层就是基于动态代理实现的实现代码先写代理对象工具 JDK动态代理 基于jdk的动态代理 业务需求 通过动态代理技术,对service层的方法统计执行时间–创建代理对象 Aop底层就是基于动态代理实现的 jdk动态代理技术是基于接口做的代理…

LNMP配置

文章目录 一、相关概念CGI的由来FastCGIPHP-FPM 二、编译安装编译安装nginxyum安装mysql编译安装php配置nginx支持php解析增加数据库安装论坛 一、相关概念 CGI的由来 最早的Web服务器只能简单地响应浏览器发来的HTTP请求&#xff0c;并将存储在服务器上的HTML文件返回给浏览器…

「动态规划」如何求粉刷房子的最少花费?

LCR 091. 粉刷房子https://leetcode.cn/problems/JEj789/description/ 假如有一排房子&#xff0c;共n个&#xff0c;每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种&#xff0c;你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。当然&#xff0c;因为市…

手把手教你通过 tensorflow-2.10 使用 BERT 实现 Semantic Similarity

前言 本文详细解释了在 tensorflow-gpu 基础上&#xff0c;实现用 BERT BILSTM 计算文本相似度的过程&#xff0c;主要的配置如下&#xff1a; tensorflow-gpu 2.10.0 python 3.10 transformers 4.26.1数据处理 这里导入了后续步骤需要用到的库&#xff0c;包括 NumPy、…

通用Mapper基础学习

一、引入 二、快速入门 1.创建测试数据 2.搭建MyBatis+Spring 开发环境 3.集成Mapper 4.第一个操作 Mapper接口源码介绍: 创建测试类: 三、常见操作

电阻常见失效模式

电阻常见失效模式&#xff1a; 电阻器由于结构较为简单&#xff0c;工艺成熟&#xff0c;通常失效率相对较低。器失效主要表现为以下几种&#xff1a; 阻值漂移&#xff1a;老化后通常发生&#xff1b;&#xff08;通过老化试验进行筛选&#xff0c;规避该问题&#xff09; …

SLT简介【简单介绍SLT】

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

如何用R语言ggplot2画折线图

文章目录 前言一、数据集二、ggplot2画图1、全部代码2、细节拆分1&#xff09;导包2&#xff09;创建图形对象3&#xff09;主题设置4&#xff09;轴设置5&#xff09;图例设置6&#xff09;颜色7&#xff09;保存图片 前言 一、数据集 数据下载链接见文章顶部 数据&#xff1a…

CentOS Stream 9 磁盘扩容

当Linux系统磁盘被占满且资料无法删除&#xff0c;需要新添加磁盘&#xff0c;并将新磁盘扩容到相应的满载磁盘中 查看现有磁盘分区 [rootwcg-lvm-001 ~]# fdisk -l Disk /dev/sda&#xff1a;180 GiB&#xff0c;193273528320 字节&#xff0c;377487360 个扇区 磁盘型号&am…

数据的加密解密——https协议

回顾http协议&#xff1a; http协议发送的请求或者响应里的2正文数据是不做任何加密的&#xff0c;数据是裸的&#xff08;原数据是什么样&#xff0c;发送过去的护具就是怎么样&#xff09;&#xff0c;但是在客户端到服务器之间是要通过中间运营商&#xff0c;路由器等中间人…

从初级到专业级,百度打破了AI的天花板

文&#xff5c;王一粟、艺思 大模型爆火一年&#xff0c;超级应用在哪里&#xff1f; 相比在ChatGPT问世时&#xff0c;人们对于“AI问答产品”寄予的超高期待&#xff0c;AI在办公场景中率先展现出来的能量&#xff0c;超出了所有人的预期。 6月7日&#xff0c;“AI产品榜”…

mmdetection使用未定义backbone训练

首先找到你需要用到的 backbone&#xff0c;一般有名的backbone 都会在github有相应的代码开源和预训练权重提供 本文以mobilenetv3 fastercnn 作为举例&#xff0c;在mmdetection中并未提供 mobilenetv3&#xff0c;提供的仅有 mobilenetv2&#xff1b; 在github上找到 mobil…

【设计模式】结构型-桥接模式

当抽象与实现&#xff0c;各自独立&#xff0c; 桥接模式&#xff0c;如彩虹桥&#xff0c;连接两岸。 文章目录 一、类爆炸与代码重复二、桥接模式三、桥接模式的核心组成四、运用桥接模式五、桥接模式的应用场景六、小结推荐阅读 一、类爆炸与代码重复 场景假设&#xff1a…

C++第二十六弹---stack和queue的基本操作详解与模拟实现

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1. stack的介绍和使用 1.1 stack的介绍 ​1.2 stack的使用 1.3 stack 模拟实现 2. queue的介绍和使用 2.1 queue的介绍 2.2 queue的使用 2…

5.31.15 使用图像到图像转换和 YOLO 技术对先前的乳房 X 光检查结果中的异常进行早期检测和分类

在本研究中&#xff0c;我们研究了基于 You-Only-Look-Once (YOLO) 架构的端到端融合模型的有效性&#xff0c;该模型可同时检测和分类数字乳房 X 光检查中的可疑乳腺病变。包括四类病例&#xff1a;肿块、钙化、结构扭曲和正常&#xff0c;这些病例来自包含 413 个病例的私人数…

一次曝 9 个大模型,「字节 AI」这一年都在做什么?

字节跳动的大模型家族&#xff0c;会长出下一个抖音吗&#xff1f; 整个 2023 年&#xff0c;字节并没有对外官宣其内部自研的大模型。外界一度认为&#xff0c;大模型这一技术变革&#xff0c;字节入场晚了。梁汝波在去年底的年会上也提到了这一点&#xff0c;他表示「字节对…