因为我暂时不需要第五章和第六章教程的内容所以直接进入第七章。感兴趣的可以访问原作者网站
注:本次封装的css样式应该有点问题,但考虑时间问题没有认真修改,后续有时间重构时候补上。
组件封装
模块化,提升后期的可维护性
组件结构
Home.vue
<template> <div class="container"> <!-- 头部区域 --> <header-bar></header-bar> <!-- 导航菜单栏 --> <menu-bar></menu-bar> <!-- 主要内容区域 --> <main-c></main-c> </div> </template> <script> import HeaderBar from './HeadBar/HeadBar'; import MenuBar from './MenuBar/MenuBar'; import MainC from './Main/Main' export default { components: { HeaderBar, MenuBar, MainC } } </script> <style lang="scss" scoped> .container { position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: #4b5f6e; } </style>
HeadBar.vue
<template> <div class="header-container"> <!-- 导航菜单隐藏显示切换 --> <!-- icon @click.prevent: 阻止默认行为 --> <span class="collapse-switcher" @click.prevent="collapse"> <i class="el-icon-menu"></i> </span> <!-- 导航菜单 --> <span class="nav-bar"> <el-menu :default-active="activeIndex" class="el-menu-demo" background-color="#4b5f6e;" text-color="#fff" active-text-color="#ffd04b" mode="horizontal" @select="handleSelectHearNavBar" > <!-- index 唯一标志 默认值 null --> <el-menu-item index="1" @click="$router.push('/')">首页</el-menu-item> <el-menu-item index="2">消息中心</el-menu-item> <el-menu-item index="3">订单管理</el-menu-item> </el-menu> </span> <span class="tool-bar"> <!-- 用户信息 --> <el-dropdown class="user-info-dropdown" trigger="hover"> <span class="el-dropdown-link userinfo-inner"> <img :src="this.userAvatar" /> {{ username }} </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>我的消息</el-dropdown-item> <el-dropdown-item>设置</el-dropdown-item> <!-- 自定义组件 @click + .native 后才能触发 --> <el-dropdown-item divided @click.native="logout">退出登入</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </span> </div> </template> <script> import mock from "@/mock/index.js"; export default { data() { return { isCollapse: false, username: "Louis", userAvatar: "", activeIndex: '1' }; }, methods: { selectNavBar(key, keyPath) { console.log(key, keyPath) }, //折叠导航栏 collapse: function() { this.isCollapse = !this.isCollapse; }, //退出登录 logout: function() { var _this = this; this.$confirm("确认退出吗?", "提示", { type: "warning" }) .then(() => { sessionStorage.removeItem("user"); this.$router.push ("/login"); }) .catch(() => {}); } }, mounted() { this.sysName = "I like Kitty"; var user = sessionStorage.getItem("user"); if (user) { this.userName = user; this.userAvatar = require("@/assets/user/user.png"); } } }; </script> <style scoped lang="scss"> .header-container { position: absolute; left: 200px; right: 0; height: 60px; line-height: 60px; .collapse-switcher { 40px; float: left; cursor: pointer; background: #504e6180; color: #fff; border: 1 solid rgba(111, 123, 131, 0.8); } .nav-bar { margin-left: auto; float: left; .el-menu { background: #504e6180; } } .tool-bar { float: right; .user-info-dropdown { font-size: 20px; padding-right: 20px; color: #fff; cursor: pointer; img { 40px; height: 40px; border-radius: 10px; margin: 10px 0px 10px 10px; float: right; } } } } </style>
MenuBar.vue
<template> <div class="menu-bar-container"> <!-- logo --> <div class="logo" :class="isCollapse?'menu-bar-collapse-width':'menu-bar-width'"> <img :src="this.logo" /> <div>{{isCollapse?'':sysName}}</div> </div> <!-- 导航菜单 --> <el-menu default-active="1-1" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleopen" @close="handleclose" @select="handleselect" > <!-- 这里的两个 slot 不懂 --> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span slot="title">系统管理</span> </template> <el-menu-item index="1-1" @click="$router.push('user')">用户管理</el-menu-item> <el-menu-item index="1-2" @click="$router.push('dept')">dept</el-menu-item> <el-menu-item index="1-3" @click="$router.push('role')">role</el-menu-item> <el-menu-item index="1-4" @click="$router.push('menu')">菜单管理</el-menu-item> <el-menu-item index="1-5" @click="$router.push('log')">log</el-menu-item> </el-submenu> <el-submenu index="2"> <template slot="title"> <i class="el-icon-location"></i> <span slot="title">系统监控</span> </template> <el-menu-item index="2-1" @click="$router.push('user')">服务监控</el-menu-item> <el-menu-item index="2-2" @click="$router.push('menu')">任务监控</el-menu-item> </el-submenu> <el-menu-item index="3" disabled> <i class="el-icon-document"></i> <span slot="title">导航三</span> </el-menu-item> <el-menu-item index="4"> <i class="el-icon-setting"></i> <span slot="title">导航四</span> </el-menu-item> </el-menu> </div> </template> <script> import mock from '@/mock/index.js'; export default { name: 'Home', data() { return { isCollapse: false, sysName: "", logo: "", } }, methods: { handleopen() { console.log('handleopen'); }, handleclose() { console.log('handleclose'); }, handleselect(a, b) { console.log('handleselect'); }, }, // 页面属性初始化 mounted() { this.sysName = "I like Kitty"; this.logo = require("@/assets/user/logo.png"); } } </script> <style scoped lang="scss"> .menu-bar-container { .el-menu { position:absolute; top: 60px; bottom: 0px; text-align: left; } .logo { position:absolute; top: 0px; height: 60px; line-height: 60px; background: #4b5f6e; img { 40px; height: 40px; border-radius: 0px; margin: 10px 10px 10px 10px; float: left; } div { font-size: 22px; color: white; text-align: left; } } .menu-bar-width { 200px; } .menu-bar-collapse-width { 65px; } } </style>
Main.vue
<template> <div class="main-container"> <el-breadcrumb separator="/" class="breadcrumb"> <el-breadcrumb-item v-for="item in $route.matched" :key="item.path"> <a href="www.baidu.com">{{ item.name }}</a> </el-breadcrumb-item> </el-breadcrumb> <transition name="fade" mode="out-in"> <router-view></router-view> </transition> </div> </template> <script> export default { data() { return { }; }, methods: { }, mounted() { } }; </script> <style scoped lang="scss"> .main-container { position: absolute; top: 60px; bottom: 0px; left: 200px; right: 0px; background: #fff; .breadcrumb { padding: 10px; border-color: rgba(38, 86, 114, 0.2); border-bottom- 1px; border-bottom-style: solid; background: rgba(138, 158, 170, 0.2); } } </style>
然后修改路由
import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter); const routes = [ { path: "/", name: "Home", component: () => import ("@/views/home"), children: [ { path: '', name: '系统介绍', component: () => import ("@/views/Intro") }, { path: '/user', name: '用户管理', component: () => import ("@/views/SysMng/User") }, { path: '/dept', name: '系统介绍', component: () => import ("@/views/SysMng/Dept") }, { path: '/role', name: '系统介绍', component: () => import ("@/views/SysMng/Role") }, { path: '/menu', name: '菜单管理', component: () => import ("@/views/SysMng/Menu") }, { path: '/log', name: '系统介绍', component: () => import ("@/views/SysMng/Log") }, ] }, { path: '/login', name: 'Login', component: () => import ("@/views/common/Login") }, { path: '/404', name: 'notFound', component: () => import ("@/views/common/404") } ]; const router = new VueRouter({ routes }); // 导航守卫 router.beforeEach((to, from, next) => { // 登入界面成功之后,会把用户信息保存在会话 // 存在时间为会话生命周期,页面关闭既失效 let user = sessionStorage.getItem('user'); if(to.path == '/login') { // 访问登入界面,如果用户会话信息存在,代表已登入过,转跳到主页 if(user) { next({ path: '/' }) }else { next() } }else { // 访问非登入界面,且用户信息不存在,代表未登入,则转跳到登入界面 if(!user) { next({ path: '/login' }) }else { next() } } }) export default router;