• 【vue实战项目】通用管理系统:首页


    前言

    本文为博主的vue实战小项目系列中的第三篇,很适合后端或者才入门的小伙伴看,一个前端项目从0到1的保姆级教学。前面的内容:

    【vue实战项目】通用管理系统:登录页-CSDN博客

    【vue实战项目】通用管理系统:封装token操作和网络请求-CSDN博客

    【vue实战项目】通用管理系统:api封装、404页-CSDN博客

    本文将讲解实现整个项目的重点:首页的搭建,包含菜单、菜单的路由转跳、面包屑导航等内容。

    目录

    1.搭架子

    2.布局

    ​编辑

    3.Header

    4.Footer

    5.Menu

    5.1.页面

    5.2.路由

    5.2.1自定义菜单内容

    5.2.2.开启路由功能

    6.面包屑导航


    1.搭架子

    先来看一下主页的样子:

    主页的结构:头部+中间+底部,也就是由header、menu、footer三个组件组成。由于这三个组件是很多页面都要用到的公共组件,所以在components下面建一个common用来放这些公共组件。然后分别建三个组件的架子,先建三个空白的架子吧,后面一点点往这三个组件里填内容。

    先把这三个组件写出来,先写三个空白的架子即可,后面再慢慢填充:

    header:

    1. <template>
    2. <div>
    3. footer
    4. div>
    5. template>
    6. <script>
    7. export default{
    8. data(){
    9. return {}
    10. }
    11. }
    12. script>
    13. <style lang="less" scoped>
    14. style>

    footer:

    1. <template>
    2. <div>
    3. footer
    4. div>
    5. template>
    6. <script>
    7. export default{
    8. data(){
    9. return {}
    10. }
    11. }
    12. script>
    13. <style lang="less" scoped>
    14. style>

    menu:

    1. <template>
    2. <div>
    3. menu
    4. div>
    5. template>
    6. <script>
    7. export default{
    8. data(){
    9. return {}
    10. }
    11. }
    12. script>
    13. <style lang="less" scoped>
    14. style>

    在helloworld组件里面引入一下,看看能不能正常引入:

    1. <template>
    2. <div class="helloworld">
    3. <Header>Header>
    4. <Menu/>
    5. <Footer/>
    6. div>
    7. template>
    8. <script>
    9. import Footer from './common/Footer.vue'
    10. import Header from './common/Header.vue'
    11. import Menu from './common/Menu.vue'
    12. export default {
    13. components:{
    14. Footer,
    15. Menu,
    16. Header
    17. },
    18. data(){
    19. return{}
    20. }
    21. }
    22. script>

    能正常引入的话,页面上会显示几个组件的内容:

    然后基于原来的HelloWorld改成Home页面:

    1. <template>
    2. <div class="home">
    3. <Header>Header>
    4. <Menu/>
    5. <Footer/>
    6. div>
    7. template>
    8. <script>
    9. import Footer from './common/Footer.vue'
    10. import Header from './common/Header.vue'
    11. import Menu from './common/Menu.vue'
    12. export default {
    13. components:{
    14. Footer,
    15. Menu,
    16. Header
    17. },
    18. data(){
    19. return{}
    20. }
    21. }
    22. script>
    23. <style lang="less">
    24. .home{
    25. width: 100%;
    26. height: 100%;
    27. }
    28. style>

    2.布局

    准备好三个组件后,接下来就是对Home进行布局,既然用了UI框架,直接用elementUI提供的布局即可,在其官网上有:

    选一个,改一改,然后调整一下样式:

    3.Header

    接下来需要调整一下header,根据上面的效果图可以看到,header上面要显示系统的名字和登录用户的用户名。系统名称直接写死,用户名可以用到我们之前封装的setToken.js去取登陆后我们放在缓存中的username作为用户名来显示。

    1. <template>
    2. <div>
    3. <el-header>
    4. <div class="title">通用管理系统div>
    5. <div>{{name}}div>
    6. el-header>
    7. div>
    8. template>
    9. <script>
    10. import {getToken} from '@/utils/setToken.js'
    11. export default{
    12. data(){
    13. return {
    14. name:''
    15. }
    16. },
    17. created(){
    18. this.name=getToken('username')
    19. }
    20. }
    21. script>
    22. <style lang="less" scoped>
    23. style>

    系统名称要在最左边,用户名要在最右边,所以调整一下样式:

    1. <template>
    2. <div class="header">
    3. <el-header>
    4. <div class="title">通用管理系统div>
    5. <div>{{name}}div>
    6. el-header>
    7. div>
    8. template>
    9. <script>
    10. import {getToken} from '@/utils/setToken.js'
    11. export default{
    12. data(){
    13. return {
    14. name:''
    15. }
    16. },
    17. created(){
    18. this.name=getToken('username')
    19. }
    20. }
    21. script>
    22. <style lang="less" scoped>
    23. .header{
    24. .el-header{
    25. background: #2578b5;
    26. color: #fff;
    27. line-height: 60px;
    28. display: flex;
    29. justify-content: space-between;
    30. .title{
    31. width:200px;
    32. font-size: 24px;
    33. }
    34. }
    35. }
    36. style>

    这样Header就处理好了。

    4.Footer

    footer比较简单,用一个el-card来包裹,加上一些文字内容就可以了。

    1. <template>
    2. <div class="footer">
    3. <el-card>Frontend 2023 BugManel-card>
    4. div>
    5. template>
    6. <script>
    7. export default{
    8. data(){
    9. return {}
    10. }
    11. }
    12. script>
    13. <style lang="less" scoped>
    14. style>

    5.Menu

    5.1.页面

    菜单组件elementUI也提供了:

    去找一个,然后调整一下即可:

    1. <template>
    2. <div class="menu">
    3. <el-aside width="200px">
    4. <el-col :span="12">
    5. <h5>自定义颜色h5>
    6. <el-menu
    7. default-active="2"
    8. class="el-menu-vertical-demo"
    9. @open="handleOpen"
    10. @close="handleClose"
    11. background-color="#545c64"
    12. text-color="#fff"
    13. active-text-color="#ffd04b"
    14. >
    15. <el-submenu index="1">
    16. <template slot="title">
    17. <i class="el-icon-location">i>
    18. <span>导航一span>
    19. template>
    20. <el-menu-item-group>
    21. <template slot="title">分组一template>
    22. <el-menu-item index="1-1">选项1el-menu-item>
    23. <el-menu-item index="1-2">选项2el-menu-item>
    24. el-menu-item-group>
    25. <el-menu-item-group title="分组2">
    26. <el-menu-item index="1-3">选项3el-menu-item>
    27. el-menu-item-group>
    28. <el-submenu index="1-4">
    29. <template slot="title">选项4template>
    30. <el-menu-item index="1-4-1">选项1el-menu-item>
    31. el-submenu>
    32. el-submenu>
    33. <el-menu-item index="2">
    34. <i class="el-icon-menu">i>
    35. <span slot="title">导航二span>
    36. el-menu-item>
    37. <el-menu-item index="3" disabled>
    38. <i class="el-icon-document">i>
    39. <span slot="title">导航三span>
    40. el-menu-item>
    41. <el-menu-item index="4">
    42. <i class="el-icon-setting">i>
    43. <span slot="title">导航四span>
    44. el-menu-item>
    45. el-menu>
    46. el-col>
    47. el-aside>
    48. div>
    49. template>
    50. <script>
    51. export default {
    52. data() {
    53. return {};
    54. },
    55. methods: {
    56. handleOpen(key, keyPath) {
    57. console.log(key, keyPath);
    58. },
    59. handleClose(key, keyPath) {
    60. console.log(key, keyPath);
    61. },
    62. },
    63. };
    64. script>
    65. <style lang="less" scoped>style>

    看一下效果图,会发现菜单虽然是引进去了,但是样式很奇怪,所以接下来要做的就是调整菜单样式。

    有左右和上下的滑动条说明高度和宽度不够,将高度拉到100%,宽度调宽一点即可。背景色不和谐,需要手动调整一下背景色。具体的样式调整后整个menu组件内容如下:

    1. <template>
    2. <div class="menu">
    3. <el-aside width="200px">
    4. <el-menu
    5. default-active="2"
    6. class="el-menu-vertical-demo"
    7. @open="handleOpen"
    8. @close="handleClose"
    9. background-color="#2578b5"
    10. text-color="#fff"
    11. active-text-color="#ffd04b"
    12. >
    13. <el-submenu index="1">
    14. <template slot="title">
    15. <i class="el-icon-location">i>
    16. <span>导航一span>
    17. template>
    18. <el-menu-item-group>
    19. <template slot="title">分组一template>
    20. <el-menu-item index="1-1">选项1el-menu-item>
    21. <el-menu-item index="1-2">选项2el-menu-item>
    22. el-menu-item-group>
    23. <el-menu-item-group title="分组2">
    24. <el-menu-item index="1-3">选项3el-menu-item>
    25. el-menu-item-group>
    26. <el-submenu index="1-4">
    27. <template slot="title">选项4template>
    28. <el-menu-item index="1-4-1">选项1el-menu-item>
    29. el-submenu>
    30. el-submenu>
    31. <el-menu-item index="2">
    32. <i class="el-icon-menu">i>
    33. <span slot="title">导航二span>
    34. el-menu-item>
    35. <el-menu-item index="3" disabled>
    36. <i class="el-icon-document">i>
    37. <span slot="title">导航三span>
    38. el-menu-item>
    39. <el-menu-item index="4">
    40. <i class="el-icon-setting">i>
    41. <span slot="title">导航四span>
    42. el-menu-item>
    43. el-menu>
    44. el-aside>
    45. div>
    46. template>
    47. <script>
    48. export default {
    49. data() {
    50. return {};
    51. },
    52. methods: {
    53. handleOpen(key, keyPath) {
    54. console.log(key, keyPath);
    55. },
    56. handleClose(key, keyPath) {
    57. console.log(key, keyPath);
    58. },
    59. },
    60. };
    61. script>
    62. <style lang="less" scoped>
    63. .menu{
    64. .el-aside{
    65. height: 100%;
    66. .el-menu{
    67. height:100%;
    68. }
    69. .el-submenu .el-menu-item{
    70. min-width: 0;
    71. }
    72. }
    73. }
    74. style>

    调整后的效果:

    我们其实用不到那么多一级菜单,只保留一个导航一即可,并且其实我们也不需要elementUI自带的示例里面给出的handleOpen和handleClose方法,所以这里再整理一下页面,最终的内容和效果如下:

    1. <template>
    2. <div class="menu">
    3. <el-aside width="200px">
    4. <el-menu
    5. default-active="2"
    6. class="el-menu-vertical-demo"
    7. background-color="#2578b5"
    8. text-color="#fff"
    9. active-text-color="#ffd04b"
    10. >
    11. <el-submenu index="1">
    12. <template slot="title">
    13. <i class="el-icon-location">i>
    14. <span>导航一span>
    15. template>
    16. <el-menu-item-group>
    17. <el-menu-item index="1-1">选项1el-menu-item>
    18. <el-menu-item index="1-2">选项2el-menu-item>
    19. el-menu-item-group>
    20. el-submenu>
    21. el-menu>
    22. el-aside>
    23. div>
    24. template>
    25. <script>
    26. export default {
    27. data() {
    28. return {};
    29. },
    30. };
    31. script>
    32. <style lang="less" scoped>
    33. .menu{
    34. .el-aside{
    35. height: 100%;
    36. .el-menu{
    37. height:100%;
    38. }
    39. .el-submenu .el-menu-item{
    40. min-width: 0;
    41. }
    42. }
    43. }
    44. style>

    最终调整后的效果:

    5.2.路由

    5.2.1自定义菜单内容

    菜单最核心的内容自然是点某一项转跳到某一个组件上去。接下来我们要完成的就是菜单的路由转跳。

    首先改写一下路由文件:

    1. import Vue from 'vue'
    2. import Router from 'vue-router'
    3. Vue.use(Router)
    4. export default new Router({
    5. routes:[
    6. {
    7. path:'/',
    8. redirect:'/login',
    9. component: ()=>import('@/components/Login')
    10. },
    11. {
    12. path:'/login',
    13. name:'Login',
    14. component: ()=>import('@/components/Login')
    15. },
    16. {
    17. path:'/home',
    18. name:'学生管理',
    19. iconClass:'fa fa-users',
    20. //默认转跳到学生管理页
    21. redirect:'/home/student',
    22. component: ()=>import('@/components/Home'),
    23. children:[
    24. {
    25. path:'/home/student',
    26. name:'学生列表',
    27. iconClass:'fa fa-list',
    28. component: ()=>import('@/components/students/StudentList'),
    29. },
    30. {
    31. path:'/home/info',
    32. name:'信息列表',
    33. iconClass:'fa fa-list-alt',
    34. component: ()=>import('@/components/students/InfoList'),
    35. },
    36. {
    37. path:'/home/info',
    38. name:'信息管理',
    39. iconClass:'fa fa-list-alt',
    40. component: ()=>import('@/components/students/InfoLists'),
    41. },
    42. {
    43. path:'/home/work',
    44. name:'作业列表',
    45. iconClass:'fa fa-list-ul',
    46. component: ()=>import('@/components/students/WorkList'),
    47. },
    48. {
    49. path:'/home/info',
    50. name:'作业管理',
    51. iconClass:'fa fa-list',
    52. component: ()=>import('@/components/students/WorkMent'),
    53. }
    54. ]
    55. },
    56. {
    57. path:'/home/dataview',
    58. name:'数据分析',
    59. iconClass:'fa fa-bar-chart',
    60. component: ()=>import('@/components/Home'),
    61. children:[
    62. {
    63. path:'/home/dataview',
    64. name:'数据概览',
    65. iconClass:'fa fa-list',
    66. component: ()=>import('@/components/dataAnalysis/DataView'),
    67. },
    68. {
    69. path:'/home/mapview',
    70. name:'地图概览',
    71. iconClass:'fa fa-line-chart',
    72. component: ()=>import('@/components/dataAnalysis/DataView'),
    73. },
    74. {
    75. path:'/home/travel',
    76. name:'旅游地图',
    77. iconClass:'fa fa-line-chart',
    78. component: ()=>import('@/components/dataAnalysis/ScoreMap'),
    79. },
    80. {
    81. path:'/home/score',
    82. name:'分数地图',
    83. iconClass:'fa fa-line-chart',
    84. component: ()=>import('@/components/dataAnalysis/TravelMap'),
    85. }
    86. ]
    87. },
    88. {
    89. path:'/users',
    90. name:'用户中心',
    91. iconClass:'fa fa-user',
    92. component: ()=>import('@/components/Home'),
    93. children:[
    94. {
    95. path:'/home/user',
    96. name:'用户概览',
    97. iconClass:'fa fa-list',
    98. component: ()=>import('@/components/users/User'),
    99. }
    100. ]
    101. },
    102. {
    103. path:'*',
    104. name:'NotFound',
    105. component:()=>import('@/components/NotFound')
    106. }
    107. ],
    108. mode:'history'
    109. })

    在menu中打印一下看能不能取到配置好的index.js的内容:

    可以看到是有数据的,有数据那就很好办了:

    去遍历菜单把数据取出来,绑定到菜单栏上去即可:

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. menus:[]
    6. };
    7. },
    8. created(){
    9. console.log(this.$router.options.routes);
    10. this.menus=[...this.$router.options.routes]
    11. }
    12. };
    13. script>
    14. <style lang="less" scoped>
    15. .menu{
    16. .el-aside{
    17. height: 100%;
    18. .el-menu{
    19. height:100%;
    20. }
    21. .el-submenu .el-menu-item{
    22. min-width: 0;
    23. }
    24. }
    25. }
    26. style>

    可以看到已经取到我们配置的导航菜单了:

    会发现还有一个问题,Login、用户中心、404页并不是我们想展示出来的,这里需要给菜单项加上一个是否隐藏的属性,在遍历时去判断该属性从而决定是不是要显示:

    1. import Vue from 'vue'
    2. import Router from 'vue-router'
    3. Vue.use(Router)
    4. export default new Router({
    5. routes:[
    6. {
    7. path:'/',
    8. redirect:'/login',
    9. hidden:true,
    10. component: ()=>import('@/components/Login')
    11. },
    12. {
    13. path:'/login',
    14. name:'Login',
    15. hidden:true,
    16. component: ()=>import('@/components/Login')
    17. },
    18. {
    19. path:'/home',
    20. name:'学生管理',
    21. iconClass:'fa fa-users',
    22. //默认转跳到学生管理页
    23. redirect:'/home/student',
    24. component: ()=>import('@/components/Home'),
    25. children:[
    26. {
    27. path:'/home/student',
    28. name:'学生列表',
    29. iconClass:'fa fa-list',
    30. component: ()=>import('@/components/students/StudentList'),
    31. },
    32. {
    33. path:'/home/info',
    34. name:'信息列表',
    35. iconClass:'fa fa-list-alt',
    36. component: ()=>import('@/components/students/InfoList'),
    37. },
    38. {
    39. path:'/home/info',
    40. name:'信息管理',
    41. iconClass:'fa fa-list-alt',
    42. component: ()=>import('@/components/students/InfoLists'),
    43. },
    44. {
    45. path:'/home/work',
    46. name:'作业列表',
    47. iconClass:'fa fa-list-ul',
    48. component: ()=>import('@/components/students/WorkList'),
    49. },
    50. {
    51. path:'/home/info',
    52. name:'作业管理',
    53. iconClass:'fa fa-list',
    54. component: ()=>import('@/components/students/WorkMent'),
    55. }
    56. ]
    57. },
    58. {
    59. path:'/home/dataview',
    60. name:'数据分析',
    61. iconClass:'fa fa-bar-chart',
    62. component: ()=>import('@/components/Home'),
    63. children:[
    64. {
    65. path:'/home/dataview',
    66. name:'数据概览',
    67. iconClass:'fa fa-list',
    68. component: ()=>import('@/components/dataAnalysis/DataView'),
    69. },
    70. {
    71. path:'/home/mapview',
    72. name:'地图概览',
    73. iconClass:'fa fa-line-chart',
    74. component: ()=>import('@/components/dataAnalysis/DataView'),
    75. },
    76. {
    77. path:'/home/travel',
    78. name:'旅游地图',
    79. iconClass:'fa fa-line-chart',
    80. component: ()=>import('@/components/dataAnalysis/ScoreMap'),
    81. },
    82. {
    83. path:'/home/score',
    84. name:'分数地图',
    85. iconClass:'fa fa-line-chart',
    86. component: ()=>import('@/components/dataAnalysis/TravelMap'),
    87. }
    88. ]
    89. },
    90. {
    91. path:'/users',
    92. name:'用户中心',
    93. iconClass:'fa fa-user',
    94. component: ()=>import('@/components/Home'),
    95. children:[
    96. {
    97. path:'/home/user',
    98. name:'用户概览',
    99. iconClass:'fa fa-list',
    100. component: ()=>import('@/components/users/User'),
    101. }
    102. ]
    103. },
    104. {
    105. path:'*',
    106. name:'NotFound',
    107. hidden:true,
    108. component:()=>import('@/components/NotFound')
    109. }
    110. ],
    111. mode:'history'
    112. })
    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. menus:[]
    6. };
    7. },
    8. created(){
    9. console.log(this.$router.options.routes);
    10. this.menus=[...this.$router.options.routes]
    11. }
    12. };
    13. script>
    14. <style lang="less" scoped>
    15. .menu{
    16. .el-aside{
    17. height: 100%;
    18. .el-menu{
    19. height:100%;
    20. }
    21. .el-submenu .el-menu-item{
    22. min-width: 0;
    23. }
    24. }
    25. }
    26. style>

    效果:

    把二级菜单一起调整出来:

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. menus:[]
    6. };
    7. },
    8. created(){
    9. console.log(this.$router.options.routes);
    10. this.menus=[...this.$router.options.routes]
    11. }
    12. };
    13. script>
    14. <style lang="less" scoped>
    15. .menu{
    16. .el-aside{
    17. height: 100%;
    18. .el-menu{
    19. height:100%;
    20. .fa{
    21. margin-right: 10px;
    22. }
    23. }
    24. .el-submenu .el-menu-item{
    25. min-width: 0;
    26. }
    27. }
    28. }
    29. style>

    5.2.2.开启路由功能

    先给meun组件上的elementUI的导航栏开启路由功能,这样点击导航栏,路径才会对应转跳:

    1. <el-menu
    2. router
    3. default-active="2"
    4. class="el-menu-vertical-demo"
    5. background-color="#2578b5"
    6. text-color="#fff"
    7. active-text-color="#ffd04b"
    8. >

    然后在home上给出路由出口:

    1. <template>
    2. <div class="home">
    3. <Header/>
    4. <el-container class="content">
    5. <Menu/>
    6. <el-container>
    7. <el-main><router-view>router-view>el-main>
    8. <el-footer><Footer/>el-footer>
    9. el-container>
    10. el-container>
    11. div>
    12. template>

    可以看到路由可以正常工作了:

    6.面包屑导航

    整个首页的架子已经搭好了,也完成了菜单的转跳,但是还差个细节就是面包屑导航栏:

    去elementUI官网上找一个面包屑的导航组件:

    在common下面新建一个面包屑组件,调整一下官网上扣下来的内容,使得其可以取到我们真实菜单的内容:

    Home里面引入使用一下即可:

    1. <template>
    2. <div class="home">
    3. <Header/>
    4. <el-container class="content">
    5. <Menu/>
    6. <el-container>
    7. <el-main>
    8. <Breadcrumb/>
    9. <router-view>router-view>
    10. el-main>
    11. <el-footer><Footer/>el-footer>
    12. el-container>
    13. el-container>
    14. div>
    15. template>
    16. <script>
    17. import Footer from './common/Footer.vue'
    18. import Header from './common/Header.vue'
    19. import Menu from './common/Menu.vue'
    20. import Breadcrumb from './common/Breadcrumb.vue'
    21. export default {
    22. components:{
    23. Footer,
    24. Menu,
    25. Header,
    26. Breadcrumb
    27. },
    28. data(){
    29. return{}
    30. }
    31. }
    32. script>
    33. <style lang="less">
    34. .home{
    35. width: 100%;
    36. height: 100%;
    37. .content{
    38. position: absolute;
    39. width: 100%;
    40. top: 60px;
    41. bottom: 0;
    42. }
    43. }
    44. style>

  • 相关阅读:
    【数据库】时区及JDBC的时区设置
    广州华锐互动:炼钢工厂VR仿真实训系统
    外贸人如何快速学好英语
    贪心算法(算法竞赛、蓝桥杯)--排队接水问题
    计算机毕业设计Java智慧防疫上报系统服务端(源码+系统+mysql数据库+Lw文档)
    Python matplot工具包之一的 mpl_toolkits绘制属于你的世界地图
    SpringCloud-Rest微服务工程的构建
    力扣:组合之和2java
    并发性,时间和相对性(2)
    浅谈微服务的发展以及可观测性
  • 原文地址:https://blog.csdn.net/Joker_ZJN/article/details/134475625