Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装
因为我暂时不需要第五章和第六章教程的内容所以直接进入第七章。感兴趣的可以访问原作者网站
注:本次封装的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 {
width: 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 {
width: 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 {
width: 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 {
width: 200px;
}
.menu-bar-collapse-width {
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-width: 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;
显示效果


浙公网安备 33010602011771号