【Vue3+Element Plus】从0-1搭建后台管理系统(02)-SideBar
这一章主要完成SideBar、Header、Main的静态渲染。
SideBar
-
首先先在
src/layout
目录下创建一个SideBar
文件夹,用来存放SideBar相关的组件等,然后在SideBar
下创建index.vue
以及创建SideBarItem.vue
,index.vue 是SideBar侧边栏菜单组件 ,SideBarItem.vue 中的内容是侧边栏菜单的菜单项以及下拉菜单,也就是说index.vue与SideBarItem.vue是父子关系,到时候在index.vue中会引入使用SideBarItem.vue。
初始化SideBar/index.vue
以及SideBar/SideBarItem.vue
的模板结构
引入SideBar
所需要的Element-plus
组件,然后在Element-plus
官网找到Menu组件将代码复制过来:
js
import { ..., ElMenu, ElMenuItem, ElSubMenu } from 'element-plus'
const ElementPlusComponents = [..., ElMenu, ElMenuItem, ElSubMenu]
SideBar/index.vue
html
<template>
<div class="sidebar">
<el-menu default-active="2" class="el-menu-vertical-demo">
<SideBarItem />
</el-menu>
</div>
</template>
<script setup lang="ts">
/** 引入SideBarItem.vue */
import SideBarItem from './SideBarItem.vue'
defineOptions({
name: 'SideBar'
})
</script>
<style lang="scss" scoped>
// SideBar style
</style>
SideBar/SideBarItem.vue
html
<template>
<div class="sidebar-item">
<!-- 下拉菜单 -->
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<!-- 菜单项 -->
<el-menu-item index="1-2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<!-- 下拉菜单 -->
<el-sub-menu index="1-3">
<template #title>item four</template>
<!-- 菜单项 -->
<el-menu-item index="1-3-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<!-- 菜单项 -->
<el-menu-item index="3">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><setting /></el-icon>
<span>Navigator Four</span>
</el-menu-item>
</div>
</template>
<script setup lang="ts">
defineOptions({
name: 'SideBarItem'
})
</script>
<style lang="scss" scoped>
// SideBarItem.vue style
</style>
这些都完成之后,下一步就可以在layout
组件中中引入SideBar
组件进行展示了:
html
<template>
<div class="layout">
<el-container>
<!-- 侧边栏菜单 -->
<el-aside width="200px">
<SideBar />
</el-aside>
<el-container>
<!-- 头部 -->
<el-header>Header</el-header>
<!-- 主要内容区域 -->
<el-main>Main</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup lang="ts">
/** 引入SideBar.vue */
import SideBar from './SideBar/index.vue'
defineOptions({
name: 'Layout'
})
</script>
<style lang="scss" scoped>
// layout.vue style
</style>
让侧边栏看起来是撑满视口高度
接下来就是修饰环节了,首先让侧边栏看起来是撑满视口高度的:
-
去掉
Menu
组件本身自带的有边框html// SideBar/index.vue <style lang="scss" scoped> .el-menu { border-right: 0; } </style>
-
给
layout/index.vue
下面的el-aside
组件添加边框html// layout/index.vue <style lang="scss" scoped> .layout { .el-aside { border-right: solid 1px $border-color; } } </style>
$border-color 是一个全局scss变量,是边框的颜色,它的值为:
#dcdfe6
。
可以从上图看出侧边栏菜单的高度已经撑满了整个视口,这样我们想要的效果就达到啦~
侧边栏logo
一般情况下,侧边栏最顶部都是展示平台的logo,所以接下来就是来完成侧边栏logo的渲染。
侧边栏的logo我打算创建一个单独的组件,然后再在侧边栏组件中引入。
-
在
src/layout/sidebar
目录下创建一个Logo.vue
文件: -
Logo.vue的代码结构:
html<template> <div class="logo"> <img class="logo-image" :src="getImageUrl('logo.png')" alt="logo.png" /> <h1 class="logo-text">DaiTuAdmin</h1> </div> </template> <script setup lang="ts"> import { getImageUrl } from '@/utils/index' defineOptions({ name: 'Logo' }) </script> <style lang="scss" scoped> .logo { display: flex; // 让logo和文字一行显示 justify-content: center; // flex容器内子项水平居中 align-items: center; // flex容器内子项垂直居中 height: 50px; &-image { margin-right: 5px; width: 32px; height: 32px; } &-text { font-size: 16px; font-weight: 400; color: #fff; } } </style>
补充一下getImageUrl(imageName)
这里使用动态导入静态资源的方式引入图片资源,如果使用这种方式,那么我们就不能直接将图片的引用地址写死了,因为在打包的时候,静态资源会被编译 ,静态资源的名称会被编译成hash
的形式,而写死的图片地址就是一个字符串,打包时不会进行编译,所以也就找不到对应地址的图片资源了。
例如,开发时会是 /img.png
,在生产构建后会是 /assets/img.2d8efhg.png
。
解决这个问题,我们可以使用URL()
+import.meta.url
:
标题 | |
---|---|
URL() | new URL('相对路径', '基础路径(绝对路径)'),返回一个URL对象,可以通过href拿到基础路径与相对路径结合生成的绝对路径。注:这个相对路径是相对于基础路径的位置。 |
import.meta.url | 可以获得当前模块的 url地址(绝对路径) |
在src/utils
目录下创建了index.ts
用来放工具函数。
在index.ts
声明了一个获取图片所在绝对路径 的函数getImageUrl(imageName)
:
js
// src/utils/index.ts
export const getImageUrl (imageName: string): sting {
return new URL('../../assets/images/${imageName}, import.meta.url).href
}
logo图片选择存放在src/assets/images
目录下:
示例:返回images/logo.png
文件的绝对路径:
js
getImageUrl('logo.png') // http://127.0.0.1:5173/src/assets/images/logo.jpg
效果:
修改侧边栏的背景色
Logo.vue:
css
.logo {
background-color: $sidebar-bg-color;
}
layout/index.vue:
css
.el-aside {
background-color: $sidebar-bg-color;
}
layout/SideBar/index.vue:
html
<el-menu
background-color="#001428">
<SideBarItem />
</el-menu>
$sidebar-bg-color: #001428;
修改菜单项字体颜色,激活的菜单项字体颜色、背景,鼠标悬浮的菜单项字体颜色、背景
菜单项字体颜色
html
<el-menu
text-color="#BBB"
active-text-color="#fff">
<SideBarItem />
</el-menu>
激活的菜单项字体颜色、背景
css
.el-menu-item {
&::after {
position: absolute;
top: 50%;
left: 50%;
z-index: 0;
transform: translate(-50%, -50%) scale(0);
transform-origin: 0 bottom;
content: '';
width: 95%;
height: 80%;
background-color: $brand-color;
border-radius: 5px;
transition: transform 0.3s;
}
}
.el-menu-item.is-active {
position: relative;
span {
position: absolute;
z-index: 1;
}
&::after {
transform: translate(-50%, -50%) scale(1);
}
}
鼠标悬浮的菜单项字体颜色、背景
scss
.el-menu-item {
&.is-active {
&:hover {
span {
color: #fff;
}
}
}
}
鼠标悬停、激活的下拉菜单样式
scss
.el-sub-menu {
&.is-active {
> :deep(.el-sub-menu__title) {
color: #fff !important;
:deep(.el-icon) {
color: #fff;
}
}
}
:deep(.el-sub-menu__title) {
&:hover {
color: #fff !important;
}
}
}
效果:
🆗到这,侧边栏的初步实现就完成啦~