1. 前言
后台管理项目很多页面都是可以统一一套公共布局的。例如公共的头部,公共的侧边菜单栏,公共的面包屑,公共的标签页。这些功能不可能每个页面都去写。那公共的部分就可以抽离成一个单独的layout组件。
2.创建基于Layout的基础架构
需要考虑哪些情况:
- 登录页是不需要Layout架构的
- 大部分后台管理项目需要Layout架构
- 可能不止一个Layout,比如有些可能地图页,有些数据大屏页面,他们也不需要Layout架构,但是又不像登录页只有一个页面那么纯粹,可能是一系列页面,也需要另外公用一套Layout
2.1 准备工作-全局样式重置
// styles/reset.scss
*,
::before,
::after {
box-sizing: border-box;
border-color: currentcolor;
border-style: solid;
border-width: 0;
}
#app {
width: 100%;
height: 100%;
}
html {
box-sizing: border-box;
width: 100%;
height: 100%;
line-height: 1.5;
tab-size: 4;
text-size-adjust: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
'微软雅黑', Arial, sans-serif;
line-height: inherit;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizelegibility;
}
a {
color: inherit;
text-decoration: inherit;
}
img,
svg {
display: inline-block;
}
svg {
vertical-align: -0.15em; //因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果
}
ul,
li {
padding: 0;
margin: 0;
list-style: none;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
a,
a:focus,
a:hover {
color: inherit;
text-decoration: none;
cursor: pointer;
}
a:focus,
a:active,
div:focus {
outline: none;
}
// styles/index.scss
@import './reset';
// main.js
// ...
import router from './router'
import '@/styles/index.scss'
const app = createApp(App)
// ...
会有报错
- 没装scss
pnpm add -D sass
2.2 layout布局
<!-- layout/layout-base/index.vue -->
<script setup>
import { AppAside, AppHeader, AppBreadcrumb, AppMain, AppFooter } from './components'
</script>
<template>
<el-container class="layout-base">
<el-aside width="240px">
<app-aside></app-aside>
</el-aside>
<el-container>
<el-header>
<app-header></app-header>
</el-header>
<app-breadcrumb></app-breadcrumb>
<el-main>
<app-main></app-main>
<app-footer></app-footer>
</el-main>
</el-container>
</el-container>
</template>
<style scoped lang="scss">
.layout-base {
position: relative;
height: 100vh;
.el-container.is-vertical {
.el-main {
position: relative;
background: #f1f2f9;
display: flex;
flex-direction: column;
}
}
}
</style>
<!-- layout/layout-base/compnoents/app-aside/index.vue -->
<script setup></script>
<template>
<div>侧边栏</div>
</template>
<style scoped lang="scss"></style>
<!-- layout/layout-base/compnoents/app-header/index.vue -->
<script setup></script>
<template>
<div class="app-header">头部</div>
</template>
<style scoped lang="scss"></style>
<!-- layout/layout-base/compnoents/app-breadcrumb/index.vue -->
<script setup></script>
<template>
<div class="app-breadcrumb">
<div class="main">面包屑</div>
</div>
</template>
<style scoped lang="scss">
.app-breadcrumb {
height: 60px;
background: #f1f2f9;
padding: 10px 20px;
.main {
height: 40px;
background: #ffffff;
}
}
</style>
<!-- layout/layout-base/compnoents/app-footer/index.vue -->
<script setup></script>
<template>
<div class="app-footer">底部版权</div>
</template>
<style scoped lang="scss">
.app-footer {
height: 40px;
line-height: 40px;
text-align: center;
font-size: 14px;
}
</style>
<!-- layout/layout-base/compnoents/app-main/index.vue -->
<script setup></script>
<template>
<div class="app-main">
<router-view></router-view>
</div>
</template>
<style scoped lang="scss">
.app-main {
flex: 1;
}
</style>
// layout/layout-base/components/index.js
// 侧边栏
export { default as AppAside } from './app-aside/index.vue'
// 头部
export { default as AppHeader } from './app-header/index.vue'
// 面包屑
export { default as AppBreadcrumb } from './app-breadcrumb/index.vue'
// 中间内容区
export { default as AppMain } from './app-main/index.vue'
// 底部版权区
export { default as AppFooter } from './app-footer/index.vue'
<!--预留其他公共布局组件 layout/layout-big-screen/index.vue-->
<script setup></script>
<template>
大屏页面公共布局
<router-view></router-view>
</template>
<style scoped lang="scss"></style>
2.3 创建路由
路由需要为以后的大型项目考虑,因此参考store去按模块划分。每个文件代表一个模块,或者说是一个一级菜单。这个文件下创建这个菜单下的所有子菜单
// router/modules/ui-basic.js
import { LayoutBase } from '@/layout/'
export default [
{
path: '/ui-basic',
component: LayoutBase,
meta: {
title: 'ui-基础组件'
},
children: [
{
path: 'button',
name: 'button',
component: () => import('@/views/ui-basic/button/index.vue'),
meta: {
title: 'Button 按钮'
}
}
]
}
]
// router/modules/index.js
// ui重置-基础组件
export { default as uiBasic } from './ui-basic'
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { uiBasic } from './modules/index.js'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '',
redirect: '/ui-basic/button'
},
...uiBasic
]
})
export default router
2.3 演示页面
页面的建立。每个页面需要对应一个文件夹,该页面下的组件统一在该文件夹下创建components文件夹。
页面级的文件夹下有且仅有一个 index.vue 文件
// views/ui-basic/button/index.vue
<script setup></script>
<template>
<div class="page">
<el-button type="primary">按钮11</el-button>
</div>
</template>
<style scoped lang="scss"></style>