003.公共布局layout-整体结构设计

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>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值