页面整体布局是一个产品最外层的框架结构,往往会包含导航、侧边栏、面包屑以及内容等。

vue3-admin 中大部分页面都是基于这个 layout 的,除了个别页面如:login , 404, 401 等页面没有使用该layout。如果你想在一个项目中有多种不同的layout也是很方便的,只要在一级路由那里选择不同的layout组件就行。

  1. /foo /bar
  2. +------------------+ +-----------------+
  3. | layout | | layout |
  4. | +--------------+ | | +-------------+ |
  5. | | foo.vue | | +------------> | | bar.vue | |
  6. | | | | | | | |
  7. | +--------------+ | | +-------------+ |
  8. +------------------+ +-----------------+

效果图

访问 ‘/‘ 重定向到 ‘/dashboard’
image.png

3-1 创建layout布局组件

在src下创建layout/index.vue, 布局主要使用flex box。
image.png

  1. <template>
  2. <div class="app-wrapper">
  3. <div class="sidebar-container">sidebar</div>
  4. <div class="main-container">
  5. <div class="header">
  6. <div class="navbar">navbar</div>
  7. <div class="tags-view">tagsview</div>
  8. </div>
  9. <div class="app-main">
  10. <h2>app main</h2>
  11. <router-view></router-view>
  12. </div>
  13. </div>
  14. </div>
  15. </template>
  16. <style lang="scss" scoped>
  17. .app-wrapper {
  18. display: flex;
  19. width: 100%;
  20. height: 100%;
  21. .main-container {
  22. flex: 1;
  23. display: flex;
  24. flex-direction: column;
  25. .header {
  26. background: cyan;
  27. .navbar {
  28. height: 50px;
  29. background: #1890ff;
  30. }
  31. .tags-view {
  32. height: 34px;
  33. background: #12efff;
  34. }
  35. }
  36. .app-main {
  37. /* 50= navbar 50 如果有tagsview + 34 */
  38. min-height: calc(100vh - 84px);
  39. background: red;
  40. }
  41. }
  42. }
  43. </style>

3-2 创建Dashboard页面

src/views下创建路由页
views/dashboard/index.vue

  1. <template>
  2. <div>
  3. <h1>Dashboard page</h1>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Dashboard'
  9. }
  10. </script>

3-3 配置路由

src/router/index.ts
路由页主要作为布局组件的子路由

  1. import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
  2. import Layout from '@/layout/index.vue'
  3. const routes: Array<RouteRecordRaw> = [
  4. {
  5. path: '/',
  6. component: Layout,
  7. redirect: '/dashboard',
  8. children: [
  9. {
  10. path: 'dashboard',
  11. name: 'Dashboard',
  12. component: () => import(/* webpackChunkName: "dashboard" */ '@/views/dashboard/index.vue'),
  13. meta: {
  14. title: 'Dashboard'
  15. }
  16. }
  17. ]
  18. }
  19. ]
  20. const router = createRouter({
  21. history: createWebHashHistory(),
  22. routes
  23. })
  24. export default router

稍等还需要修正下样式

3-4 styles样式文件

样式使用sass编写,使用前先安装sass

npm install sass —save https://vitejs.cn/guide/features.html#css-pre-processors

然后在src下创建 styles目录存放全局样式文件,目前没多少样式可以直接拷贝
image.png

src\styles\index.scss

入口css

  1. @import './variables.scss';
  2. @import './sidebar.scss';
  3. html {
  4. height: 100%;
  5. box-sizing: border-box;
  6. }
  7. body {
  8. height: 100%;
  9. -moz-osx-font-smoothing: grayscale;
  10. -webkit-font-smoothing: antialiased;
  11. text-rendering: optimizeLegibility;
  12. font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
  13. }
  14. #app {
  15. height: 100%;
  16. }

src\styles\sidebar.scss

主要针对sidebar的样式

  1. #app {
  2. .sidebar-container {
  3. width: $sideBarWidth !important;
  4. height: 100%;
  5. background-color: pink;
  6. }
  7. }

src\styles\variables.scss

导出一些scss变量 可在js中使用scss变量

  1. // base color
  2. $blue:#324157;
  3. $light-blue:#3A71A8;
  4. $red:#C03639;
  5. $pink: #E65D6E;
  6. $green: #30B08F;
  7. $tiffany: #4AB7BD;
  8. $yellow:#FEC171;
  9. $panGreen: #30B08F;
  10. // sidebar
  11. $menuText:#bfcbd9;
  12. $menuActiveText:#409EFF;
  13. $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
  14. $menuBg:#304156;
  15. $menuHover:#263445;
  16. $subMenuBg:#1f2d3d;
  17. $subMenuHover:#001528;
  18. $sideBarWidth: 210px;
  19. // The :export directive is the magic sauce for webpack
  20. // https://mattferderer.com/use-sass-variables-in-typescript-and-javascript
  21. :export {
  22. menuText: $menuText;
  23. menuActiveText: $menuActiveText;
  24. subMenuActiveText: $subMenuActiveText;
  25. menuBg: $menuBg;
  26. menuHover: $menuHover;
  27. subMenuBg: $subMenuBg;
  28. subMenuHover: $subMenuHover;
  29. sideBarWidth: $sideBarWidth;
  30. }

scss类型声明文件
ts中使用sass变量 需要类型声明
参考文档 https://mattferderer.com/use-sass-variables-in-typescript-and-javascript
新建 src\styles\variables.scss.d.ts

  1. export interface ScssVariables {
  2. menuText: string;
  3. menuActiveText: string;
  4. subMenuActiveText: string;
  5. menuBg: string;
  6. menuHover: string;
  7. subMenuBg: string;
  8. subMenuHover: string;
  9. sideBarWidth: string;
  10. }
  11. export const variables: ScssVariables
  12. export default variables

最后,在src/main.ts中引入全局css
先安装normalize.css

  1. npm i normalize.css --save
  2. pnpm install normalize.css --save
  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import router from './router/index'
  4. import ElementPlus from 'element-plus';
  5. import store from './store'
  6. // 初始化css 重置css默认样式
  7. import 'normalize.css/normalize.css'
  8. // 全局 css
  9. import '@/styles/index.scss'
  10. createApp(App)
  11. .use(store)
  12. .use(router)
  13. .use(ElementPlus)
  14. .mount('#app')

本节参考源码

https://gitee.com/brolly/vue3-element-admin/commit/a24aac74b26a044efbbbea51ae687f7eb490eeab

对于每节文章有问题需要补充评论的 大家可以写在每节下方评论处 感谢