vue3后台管理系统之layout组件的搭建

1.1静态布局

<template><div class="layout_container"><!-- 左侧导航 --><div class="layout_slider"></div><!-- 顶部导航 --><div class="layout_tabbar"></div><!-- 内容展示区 --><div class="layout_main"></div></div>
</template><!-- <script lang="ts"></script> --><style scoped lang="scss">
.layout_container {width: 100%;height: 100vh;.layout_slider {color: white;width: $base-menu-width;height: 100vh;background: $base-menu-background;transition: all 0.3s;.scrollbar {width: 100%;height: calc(100vh - $base-menu-logo-height);.el-menu {border-right: none;}}}.layout_tabbar {position: fixed;width: calc(100% - $base-menu-width);height: $base-tabbar-height;top: 0px;left: $base-menu-width;transition: all 0.3s;background-color: aqua;&.fold {width: calc(100vw - $base-menu-min-width);left: $base-menu-min-width;}}.layout_main {position: absolute;width: calc(100% - $base-menu-width);height: calc(100vh - $base-tabbar-height);left: $base-menu-width;top: $base-tabbar-height;padding: 20px;overflow: auto;transition: all 0.3s;&.fold {width: calc(100vw - $base-menu-min-width);left: $base-menu-min-width;}}
}
</style>

//项目提供scss全局变量
// 左侧菜单宽度
//定义项目主题颜色//左侧的菜单的宽度
$base-menu-width     :260px;
//左侧菜单的背景颜色
$base-menu-background:#001529;
$base-menu-min-width :50px;// 顶部导航的高度
$base-tabbar-height:50px;//左侧菜单logo高度设置
$base-menu-logo-height:50px;//左侧菜单logo右侧文字大小
$base-logo-title-fontSize:20px;

1.2动态logo和标题搭建

src下创建setting.ts

// 项目图标和标题
export default {title: 'v3后台管理系统', //项目标题设置logo: '../../../../../public/logo.png', //项目配置logologoHidden: true, //logo组件是否隐藏
}

<template><div class="logo" v-if="setting.logoHidden"><img :src="setting.logo" alt="" /><p>{{ setting.title }}</p></div>
</template>
<script setup lang="ts">
import setting from '@/setting'
</script>
<style scoped lang="scss">
.logo {width: 100%;height: $base-menu-logo-height;color: white;display: flex;align-items: center;padding: 10px;img {width: 40px;height: 40px;}p {font-size: $base-logo-title-fontSize;margin-left: 10px;}
}
</style>

1.3左侧静态布局

<template><div class="layout_container"><!-- 左侧导航 --><div class="layout_slider"><Logo /><!-- 展示菜单 --><!-- 滚动组件 --><el-scrollbar class="scrollbar"><!-- 菜单组件--><el-menu background-color="#001529" text-color="white" active-text-color="yellowgreen"><el-menu-item index="1">首页</el-menu-item><el-menu-item index="1">数据大屏</el-menu-item><el-sub-menu index="2"><template #title>权限管理</template><el-menu-item index="2-1">用户管理</el-menu-item><el-menu-item index="2-2">角色管理</el-menu-item><el-menu-item index="2-3">菜单管理</el-menu-item></el-sub-menu></el-menu></el-scrollbar></div><!-- 顶部导航 --><div class="layout_tabbar"></div><!-- 内容展示区 --><div class="layout_main"><h1 style="height: 22222px; background-color: red">我是一个段落</h1></div></div>
</template>
<script setup lang="ts">
import Logo from './components/logo/index.vue'
</script><style scoped lang="scss">
.layout_container {width: 100%;height: 100vh;.layout_slider {color: white;width: $base-menu-width;height: 100vh;background: $base-menu-background;.scrollbar {width: 100%;height: calc(100vh - $base-menu-logo-height);.el-menu {border-right: none;}}}.layout_tabbar {position: fixed;width: calc(100% - $base-menu-width);height: $base-tabbar-height;top: 0px;left: $base-menu-width;background-color: aqua;}.layout_main {position: absolute;width: calc(100% - $base-menu-width);height: calc(100vh - $base-tabbar-height);left: $base-menu-width;top: $base-tabbar-height;padding: 20px;overflow: auto;background-color: yellowgreen;}
}
</style>

1.4配置左侧动态路由

store管理路由数组

//引入路由(常量路由)
import { constantRoute } from '@/router/routes'
const useUserStore = defineStore('User', {// 小仓库存储数据state: (): UserState => {return {token: GET_TOKEN(),menuRoutes: constantRoute, //仓库存储生成菜单需要数组(路由)}},

import type { RouteRecordRaw } from 'vue-router'
// 定义小仓库state数据类型
export interface UserState {token: string | nullmenuRoutes: RouteRecordRaw[]
}

传递路由数组到Menu组件

接收menuList

1.5递归组件生成菜单

修改router

添加meta

meta: {

title: ' 登录 ',

hidden: false //代表路由标题在菜单中是否隐藏

}

hidden代表是否隐藏

// 对外配置路由
import Login from '@/views/login/index.vue'
import Home from '@/views/home/index.vue'
import Error from '@/views/404/index.vue'
import Test from '@/views/test/index.vue'
import Layout from '@/layout/index.vue'
export const constantRoute = [{path: '/login',component: Login,name: 'login',meta: {title: ' 登录 ',hidden: false //代表路由标题在菜单中是否隐藏}},{path: '/',component: Layout,name: 'layout',meta: {title: 'layout ',hidden: false //代表路由标题在菜单中是否隐藏  true代表隐藏},children: [{path: '/home',component: Home,meta: {title: ' 首页 ',hidden: false //代表路由标题在菜单中是否隐藏}},{path: '/test',component: Test,meta: {title: ' 测试 ',hidden: false //代表路由标题在菜单中是否隐藏}}]},{path: '/404',component: Error,name: '404',meta: {title: ' 404 ',hidden: false //代表路由标题在菜单中是否隐藏}},{path: '/:pathMatch',redirect: '/404',name: 'Any',meta: {title: ' 任意路由 ',hidden: true //代表路由标题在菜单中是否隐藏}}
]

根据判断条件展示路由

<!-- eslint-disable vue/no-reserved-component-names -->
<template><template v-for="item in menuList" :key="item.path"><!-- 没有子路由 --><template v-if="!item.children"><el-menu-item :index="item.path" v-if="!item.meta.hidden"><template #title><!-- 图标 --><span>图标</span><span>{{ item.meta.title }}</span></template></el-menu-item></template><!-- 有子路由但是只有一个子路由 --><template v-if="item.children && item.children.length == 1"><el-menu-itemv-if="!item.children[0].meta.hidden":index="item.children[0].path"><template #title><!-- 图标 --><span>图标</span><span>{{ item.children[0].meta.title }}</span></template></el-menu-item></template><!-- 有子路由且个数大于一个 --><el-sub-menu:index="item.path"v-if="item.children && item.children.length > 1"><template #title><span>{{ item.meta.title }}</span></template><Menu :menuList="item.children"></Menu></el-sub-menu></template>
</template><script setup lang="ts">
defineProps(['menuList'])
</script>
<script lang="ts">
export default {// eslint-disable-next-line vue/no-reserved-component-namesname: 'Menu',
}
</script><style lang="scss" scoped></style>

递归组件实现

1.6配置菜单图标

注册所有图标#

您需要从 @element-plus/icons-vue 中导入所有图标并进行全局注册。

// main.ts// 如果您正在使用CDN引入,请删除下面一行。import * as ElementPlusIconsVue from '@element-plus/icons-vue'const app = createApp(App)for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}

import SvgIcon from './SvgIcon/index.vue'
import type { App, Component } from 'vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const components: { [name: string]: Component } = { SvgIcon }
export default {install(app: App) {// 注册项目全部的全局组件Object.keys(components).forEach((key: string) => {app.component(key, components[key])})// 将element-lpus提供的图标注册为全局组件for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}},
}

在meta添加属性icon

动态组件component

<!-- 图标 --><el-icon><component :is="item.meta.icon" /></el-icon>

<!-- eslint-disable vue/no-reserved-component-names -->
<template><template v-for="item in menuList" :key="item.path"><!-- 没有子路由 --><template v-if="!item.children"><el-menu-item:index="item.path"v-if="!item.meta.hidden"@click="goRoute"><template #title><!-- 图标 --><el-icon><component :is="item.meta.icon"></component></el-icon><span>{{ item.meta.title }}</span></template></el-menu-item></template><!-- 有子路由但是只有一个子路由 --><template v-if="item.children && item.children.length == 1"><el-menu-itemv-if="!item.children[0].meta.hidden":index="item.children[0].path"><template #title><!-- 图标 --><el-icon><component :is="item.children[0].meta.icon"></component></el-icon><span>{{ item.children[0].meta.title }}</span></template></el-menu-item></template><!-- 有子路由且个数大于一个 --><el-sub-menu:index="item.path"v-if="item.children && item.children.length > 1"><template #title><el-icon><component :is="item.meta.icon"></component></el-icon><span>{{ item.meta.title }}</span></template><Menu :menuList="item.children"></Menu></el-sub-menu></template>
</template><script setup lang="ts">
defineProps(['menuList'])
// 点击菜单的回调
const goRoute = (vc: any) => {console.log(vc.index)
}
</script>
<script lang="ts">
export default {// eslint-disable-next-line vue/no-reserved-component-namesname: 'Menu',
}
</script><style lang="scss" scoped></style>

1.7配置全部路由

一般后台管理系统都有登录、首页、数据大屏、权限管理这几个功能,所以接下来配置这些路由。

// 对外配置路由
import Login from '@/views/login/index.vue'
import Home from '@/views/home/index.vue'
import Error from '@/views/404/index.vue'
import Role from '@/views/acl/role/index.vue'
import User from '@/views/acl/user/index.vue'
import Scree from '@/views/scree/index.vue'
import Layout from '@/layout/index.vue'
export const constantRoute = [{path: '/login',component: Login,name: 'login',meta: {icon: 'Edit',title: ' 登录 ',hidden: true //代表路由标题在菜单中是否隐藏}},{path: '/',component: Layout,name: 'layout',meta: {title: 'layout ',hidden: false, //代表路由标题在菜单中是否隐藏  true代表隐藏icon: 'Promotion'},redirect: '/home',children: [{path: '/home',component: Home,meta: {title: ' 首页 ',hidden: false, //代表路由标题在菜单中是否隐藏icon: 'HomeFilled'}}]},{path: '/scree',component: Scree,name: 'Screen',meta: {title: '数据大屏',hidden: false,icon: 'Histogram'}},{path: '/acl',component: Layout,name: 'Acl',meta: {title: '权限管理 ',icon: 'Lock'},children: [{path: '/acl/user',component: User,meta: {title: '用户管理',hidden: false, //代表路由标题在菜单中是否隐藏icon: 'User'}},{path: '/acl/role',component: Role,meta: {title: '角色管理',hidden: false, //代表路由标题在菜单中是否隐藏icon: 'UserFilled'}}]},{path: '/404',component: Error,name: '404',meta: {icon: 'Edit',title: ' 404 ',hidden: true //代表路由标题在菜单中是否隐藏}},{path: '/:pathMatch',redirect: '/404',name: 'Any',meta: {title: ' 任意路由 ',hidden: true //代表路由标题在菜单中是否隐藏}}
]

渲染layout一级路由的子路由

1.8页面加载时默认激活菜单的 index

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

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

相关文章

Kaggle - LLM Science Exam(三):Wikipedia RAG

文章目录 一、赛事概述1.1 OpenBookQA Dataset1.2 比赛背景1.3 评估方法和代码要求1.4 比赛数据集1.5 优秀notebook 二、 [EDA, Data gathering] LLM-SE ~ Wiki STEM | 1k DS2.1 Data overview2.2 Data gathering 三、如何高效收集数据3.1 概述3.2 与训练数据关联的维基百科类别…

8.Covector Transformation Rules

上一节已知&#xff0c;任意的协向量都可以写成对偶基向量的线性组合&#xff0c;以及如何通过计算基向量穿过的协向量线来获得协向量分量&#xff0c;且看到 协向量分量 以 与向量分量 相反的方式进行变换。 现要在数学上确认协向量变换规则是什么。 第一件事&#xff1a;…

升级包版本之后Reflections反射包在springboot jar环境下扫描不到class排查过程记录

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

多继承vs查看类结构

多继承里面的虚函数 类A有两个虚函数&#xff0c;类B重写了其中一个&#xff0c;类C重写了两个&#xff1b; 类C里面可以重写所有继承到的虚函数&#xff08;类A、类B里面的虚函数&#xff09; class A { public:virtual void init() { std::cout << "A init !&qu…

计算机操作系统-第十天

目录 1、操作系统的进程 进程的概念 进程的组成------PCB 进程的组成------程序段、数据段 旧知新学&#xff1a;《程序是如何运行的》 进程的特征 本节思维导图 1、操作系统的进程 进程的概念 当我们打开多个qq程序&#xff0c;我们会发现任务管理器的进程中有…

解决方案-LBS用户位置Redis-GEO附近人/店铺

附近人 windows安装附近人列表功能mysqlredis GEO CNNVD-201511-230 未授权访问python 多线程 redis大端模式与小端模式IP地址的不同表现形式1.字符串表现形式2. 整数表现形式3.大小端模式下的IP地址 0x01 进入python正题Python的socket库1.socket.socket(family,type)2.socket…

02.机器学习原理(复习)

目录 机器学习的本质机器学习的类型Regression/回归Classification/分类Structured Learning/结构化学习 ML的三板斧设定范围设定标准监督学习半监督学习其他 达成目标小结达成目标设定标准设定范围 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》&#xff0c;B站自行搜…

10.18作业

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…

【网络安全】防火墙技术

防火墙是网络安全防御的重要组成部分&#xff0c;它的主要任务是阻止或限制不安全的网络通信。在这篇文章中&#xff0c;我们将详细介绍防火墙的工作原理&#xff0c;类型以及如何配置和使用防火墙。我们将尽可能使用简单的语言和实例&#xff0c;以便于初学者理解。 如果你对…

【字符串匹配算法】KMP、哈希

STL O(mn) C中提供子串查询的函数可以使用std::string类的相关方法来实现。 find函数&#xff1a;可以查找一个子串在原字符串中的第一个出现位置。它返回子串的起始索引&#xff0c;如果找不到则返回std::string::npos。substr函数&#xff1a;可以提取原字符串中的一个子串…

Jmeter性能测试(压力测试)

1.先保存 2.添加请求&#xff08;即添加一个线程组&#xff09; 3.添加取样器&#xff08;在线程组下面添加一个http请求&#xff09; 场景1&#xff1a;模拟半小时之内1000个用户访问服务器资源&#xff0c;要求平均响应时间在3000毫秒内&#xff0c;且错误率为0&#xff0…

Kafka SASL认证授权(六)全方位性能测试

Kafka SASL认证授权(六)全方位性能测试。 官网地址:https://kafka.apache.org/ 一、场景 线上已经有kafka集群,服务运行稳定。但是因为产品升级,需要对kakfa做安全测试,也就是权限验证。 但是增加权限验证,会不会对性能有影响呢?影响大吗?不知道呀! 因此,本文就此…

Qt/C++开源作品45-CPU内存显示控件/和任务管理器一致

一、前言 在很多软件上&#xff0c;会在某个部位显示一个部件&#xff0c;专门显示当前的CPU使用率以及内存占用&#xff0c;方便用户判断当前程序或者当前环境中是否还有剩余的CPU和内存留给程序使用&#xff0c;在不用打开任务管理器或者资源查看器的时候直接得知当前系统的…

ORACLE内存结构

内存体系结构 ​​​​​​​ 目录 内存体系结构 2.1自动内存管理 2.2自动SGA内存管理 2.3手动SGA内存管理 2.3.1数据库缓冲区 2.3.1.1保留池 2.3.1.2回收池 2.3.2共享池 2.3.2.1SQL查询结果和函数查询结果 2.3.2.2库缓存 2.3.2.3数据字典缓存 2.3.3大池 2.3.4 …

20-数据结构-内部排序-插入排序

简介&#xff1a;插入排序基本有两步&#xff0c;先是通过比较&#xff0c;得到插入位置&#xff0c;随后移动给需要插入的位置处腾空&#xff0c;最后进行值的插入。 目录 一、直接插入排序 1.1简介&#xff1a; 1.2代码 二、折半插入排序 2.1简介&#xff1a; 2.2代码…

LXC、Docker、 Kubernetes 容器以及Hypervisor的区别

LXC、Docker、 Kubernetes 容器以及Hypervisor的区别 SaaS: Software-as-a-Service&#xff08;软件即服务&#xff09; PaaS: Platform-as-a-Service&#xff08;平台即服务&#xff09; IaaS: Infrastructure-as-a-Service&#xff08;基础设施即服务&#xff09; 1、Docke…

如何使用 Disco 将黑白照片彩色化

Disco 是一个基于视觉语言模型&#xff08;LLM&#xff09;的图像彩色化工具。它使用 LLM 来生成彩色图像&#xff0c;这些图像与原始黑白图像相似。 本文将介绍如何使用 Disco 将黑白照片彩色化。 使用 Disco 提供了一个简单的在线演示&#xff0c;可以用于测试模型。 访问…

SpringMVC之国际化上传下载

spring项目中的国际化 1&#xff09;提供中英两种资源文件 i18n_en_US.properties i18n_zh_CN.properties 2&#xff09;配置国际化资源文件&#xff08;在spring配置文件中添加&#xff0c;例如spring-mvc.xml&#xff09; <bean id"messageSource" class&quo…

从头开始机器学习:神经网络

一、说明 如果你还没有做过逻辑回归&#xff0c;你会在这里挣扎。我强烈建议在开始之前查看它。您在逻辑回归方面的能力将影响您学习神经网络的难易程度和速度。 二、神经网络简介 神经网络是一个神经元网络。这些神经元是逻辑回归函数&#xff0c;它们被链接在一起形成一个网络…

使用REPLACE将数据库某一列字段进行字符串操作

REPLACE可以将表里的数据进行替换操作 如&#xff1a;需要把这一列里面的 # 去掉&#xff0c;经过测试&#xff0c;无论是开头、句中还是结尾都可以删除 UPDATE 表名 SET 字段名 REPLACE(字段名 , #, )