本节目标
1-1创建Sidebar组件
src/layout/components/Sidebar/index.vue
将layout/index.vue中导入组件
<template>
<div class="app-wrapper">
<div class="sidebar-container">
<Sidebar />
</div>
<div class="main-container">
<div class="header">
<div class="navbar">navbar</div>
<div class="tags-view">tagsview</div>
</div>
<div class="app-main">
<h2>app main</h2>
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import Sidebar from './components/Sidebar'
export default {
components: {
Sidebar
}
}
</script>
<style lang="scss" scoped>
.app-wrapper {
display: flex;
width: 100%;
height: 100%;
.main-container {
flex: 1;
display: flex;
flex-direction: column;
.header {
background: cyan;
.navbar {
height: 50px;
background: #1890ff;
}
.tags-view {
height: 34px;
background: #12efff;
}
}
.app-main {
/* 50= navbar 50 如果有tagsview + 34 */
min-height: calc(100vh - 84px);
background: red;
}
}
}
</style>
1.element.ts导入所需菜单组件
这里主要会用到 el-menu el-menu-item element组件 大家别忘了导入
2.sidebar中菜单组件属性配置
src/layout/components/Sidebar/index.vue
<template>
<div>
<!-- 测试展开收起 -->
<h8 @click="isCollapse=!isCollapse">展收测试</h8>
<el-menu
class="sidebar-container-menu"
mode="vertical"
:default-active="activeMenu"
:background-color="scssVariables.menuBg"
:text-color="scssVariables.menuText"
:active-text-color="scssVariables.menuActiveText"
:collapse="isCollapse"
:collapse-transition="true"
>
<sidebar-item />
</el-menu>
</div>
</template>
<script lang="ts">
import { defineComponent, computed, ref } from 'vue'
import { useRoute } from 'vue-router'
// 导入scss变量在组件中使用
import variables from '@/styles/variables.scss'
// el-menu-item封装
import SidebarItem from './SidebarItem.vue'
export default defineComponent({
name: 'Sidebar',
components: {
SidebarItem
},
setup() {
const route = useRoute()
// 根据路由路径 对应 当前激活的菜单 页面刷新后 激活当前路由匹配的菜单
const activeMenu = computed(() => {
const { path } = route
return path
})
// scss变量
const scssVariables = computed(() => variables)
// 菜单展开收起状态 后面会放store里
const isCollapse = ref(true)
return {
// ...toRefs(variables), // 不有toRefs原因 缺点variables里面变量属性来源不明确
scssVariables,
isCollapse,
activeMenu
}
}
})
</script>
3. 封装SidebarItem组件
src/layout/components/Sidebar/SidebarItem.vue
目前里面只有一个菜单项 大家可以测下菜单展开收起
<template>
<div class="sidebar-item-container">
<el-menu-item index="1">
<svg-icon class="menu-icon" icon-class="lock"></svg-icon>
<template #title>
<span>Dashoard</span>
</template>
</el-menu-item>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'SidebarItem'
})
</script>
<style lang="scss">
.sidebar-item-container {
.menu-icon {
margin-right: 16px;
margin-left: 5px;
vertical-align: middle;
}
}
</style>
4. sidebar 全局css样式改动
#app {
.sidebar-container {
width: $sideBarWidth !important;
height: 100%;
background-color: pink;
background-color: $menuBg;
// menu未收起时样式
&-menu:not(.el-menu--collapse) {
width: $sideBarWidth;
}
.el-menu {
border: none;
}
}
}
5.简单创建几个路由页
6.路由注册下
路由一级都是layout组件
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
// 看作是异步获取路由
export const asyncRoutes: Array<RouteRecordRaw> = [
{
path: '/documentation',
component: Layout, // 布局组件作为一级路由
redirect: '/documentation/index',
children: [
{
path: 'index',
name: 'Documentation',
component: () => import(/* webpackChunkName: "documentation" */ '@/views/documentation/index.vue'),
meta: {
title: 'Documentation',
icon: 'documentation'
}
}
]
},
{
path: '/guide',
component: Layout,
redirect: '/guide/index',
children: [
{
path: 'index',
name: 'Guide',
component: () => import(/* webpackChunkName: "guide" */ '@/views/guide/index.vue'),
meta: {
title: 'Guide',
icon: 'guide'
}
}
]
},
{
path: '/system',
component: Layout,
redirect: '/system/user',
meta: {
title: 'System',
icon: 'lock'
},
children: [
{
path: 'menu',
component: () => import(/* webpackChunkName: "menu" */ '@/views/system/menu.vue'),
meta: {
title: 'Menu Management',
icon: 'list'
}
},
{
path: 'role',
component: () => import(/* webpackChunkName: "role" */ '@/views/system/role.vue'),
meta: {
title: 'Role Management',
icon: 'list'
}
},
{
path: 'user',
component: () => import(/* webpackChunkName: "user" */ '@/views/system/user.vue'),
meta: {
title: 'User Management',
icon: 'list'
}
}
]
}
]
export const constantRoutes: Array<RouteRecordRaw> = [
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import(/* webpackChunkName: "dashboard" */ '@/views/dashboard/index.vue'),
meta: {
title: 'Dashboard'
}
}
]
}
]
export const routes = [
...constantRoutes, // 解构语法可能报波浪线tslib版本升级 没懂 暂时先不管
...asyncRoutes
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
本节源码参考
https://gitee.com/brolly/vue3-element-admin/commit/7411683e2923767adb62b051b0f9a6d12cc907e5