Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装
组件封装
为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度。
组件结构
组件封装重构后,试图组件结构如下图所示
代码一览
Home组件被简化,包含导航、头部和主内容三个组件。
Home.vue
- <template>
- <div class="container">
- <!-- 导航菜单栏 -->
- <MenuBar></MenuBar>
- <!-- 头部区域 -->
- <HeadBar></HeadBar>
- <!-- 主内容区域 -->
- <Main></Main>
- </div>
- </template>
- <script>
- import HeadBar from "./HeadBar/HeadBar"
- import MenuBar from "./MenuBar/MenuBar"
- import Main from "./Main/Main"
- export default {
- components:{
- HeadBar,
- MenuBar,
- Main
- }
- };
- </script>
- <style scoped lang="scss">
- .container {
- position:absolute;
- top: 0px;
- left: 0px;
- right: 0px;
- background: #4b5f6e;
- }
- </style>
HeadBar.vue
- <template>
- <div class="container">
- <!-- 导航菜单隐藏显示切换 -->
- <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" text-color="#fff"
- active-text-color="#ffd04b" mode="horizontal" @select="selectNavBar()">
- <el-menu-item index="1" @click="$router.push('/')">{{$t("common.home")}}</el-menu-item>
- <el-menu-item index="2">{{$t("common.doc")}}</el-menu-item>
- <el-menu-item index="3">{{$t("common.msgCenter")}}</el-menu-item>
- </el-menu>
- </span>
- <span class="tool-bar">
- <!-- 主题切换 -->
- <ThemePicker class="theme-picker"></ThemePicker>
- <!-- 语言切换 -->
- <LangSelector class="lang-selector"></LangSelector>
- <!-- 用户信息 -->
- <el-dropdown class="user-info-dropdown" trigger="hover">
- <span class="el-dropdown-link"><img :src="this.userAvatar" /> {{username}}</span>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item>{{$t("common.myMsg")}}</el-dropdown-item>
- <el-dropdown-item>{{$t("common.config")}}</el-dropdown-item>
- <el-dropdown-item divided @click.native="logout">{{$t("common.logout")}}</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </span>
- </div>
- </template>
- <script>
- import mock from "@/mock/index.js";
- import ThemePicker from "@/components/ThemePicker"
- import LangSelector from "@/components/LangSelector"
- export default {
- components:{
- ThemePicker,
- LangSelector
- },
- data() {
- return {
- isCollapse: false,
- username: "Louis",
- userAvatar: "",
- activeIndex: '1'
- };
- },
- methods: {
- selectNavBar(key, keyPath) {
- console.log(key, keyPath)
- },
- // 语言切换
- handleCommand(command) {
- let array = command.split(':')
- let lang = array[0] === '' ? 'zh_cn' : array[0]
- let label = array[1]
- document.getElementById("language").innerHTML = label
- this.$i18n.locale = lang
- },
- //折叠导航栏
- 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.png");
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .container {
- position: absolute;
- left: 200px;
- right: 0px;
- height: 60px;
- line-height: 60px;
- .collapse-switcher {
- width: 40px;
- float: left;
- cursor: pointer;
- border-color: rgba(111, 123, 131, 0.8);
- border-left-width: 1px;
- border-left-style: solid;
- border-right-width: 1px;
- border-right-style: solid;
- color: white;
- background: #504e6180;
- }
- .nav-bar {
- margin-left: auto;
- float: left;
- .el-menu {
- background: #504e6180;
- }
- }
- .tool-bar {
- float: right;
- .theme-picker {
- padding-right: 10px;
- }
- .lang-selector {
- padding-right: 10px;
- font-size: 15px;
- color: #fff;
- cursor: pointer;
- }
- .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="isCollapse?'menu-bar-collapse-width':'menu-bar-width'" @open="handleopen" @close="handleclose" @select="handleselect" :collapse="isCollapse">
- <el-submenu index="1">
- <template slot="title">
- <i class="el-icon-location"></i>
- <span slot="title">{{$t("sys.sysMng")}}</span>
- </template>
- <el-menu-item index="1-1" @click="$router.push('user')">{{$t("sys.userMng")}}</el-menu-item>
- <el-menu-item index="1-2" @click="$router.push('dept')">{{$t("sys.deptMng")}}</el-menu-item>
- <el-menu-item index="1-3" @click="$router.push('role')">{{$t("sys.roleMng")}}</el-menu-item>
- <el-menu-item index="1-4" @click="$router.push('menu')">{{$t("sys.menuMng")}}</el-menu-item>
- <el-menu-item index="1-5" @click="$router.push('log')">{{$t("sys.logMng")}}</el-menu-item>
- </el-submenu>
- <el-submenu index="2">
- <template slot="title">
- <i class="el-icon-location"></i>
- <span slot="title">{{$t("sys.sysMonitor")}}</span>
- </template>
- </el-submenu>
- <el-menu-item index="3" disabled>
- <i class="el-icon-document"></i>
- <span slot="title">{{$t("sys.nav3")}}</span>
- </el-menu-item>
- <el-menu-item index="4">
- <i class="el-icon-setting"></i>
- <span slot="title">{{$t("sys.nv4")}}</span>
- </el-menu-item>
- </el-menu>
- </div>
- </template>
- <script>
- export default {
- 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/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="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">
- .container {
- position: absolute;
- top: 60px;
- bottom: 0px;
- left: 200px;
- right: 0px;
- .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>
国际化语言切换也被封装成为了组件 LangSelector
LangSelector/index.js
- <template>
- <el-dropdown class="lang-selector" @command="handleCommand">
- <span class="el-dropdown-link">
- <span id="language">中文</span><i class="el-icon-arrow-down el-icon--right"></i>
- </span>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item command="zh_cn:中文">中文</el-dropdown-item>
- <el-dropdown-item command="en_us:English">English</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </template>
- <script>
- export default {
- methods: {
- // 语言切换
- handleCommand(command) {
- let array = command.split(':')
- let lang = array[0] === '' ? 'zh_cn' : array[0]
- let label = array[1]
- document.getElementById("language").innerHTML = label
- this.$i18n.locale = lang
- }
- }
- }
- </script>
组件封装重构之后,同步修改路由配置
- import Vue from 'vue'
- import Router from 'vue-router'
- import Login from '@/views/Login'
- import NotFound from '@/views/404'
- import Home from '@/views/Home'
- import Intro from '@/views/Intro'
- import User from '@/views/SysMng/User'
- import Dept from '@/views/SysMng/Dept'
- import Role from '@/views/SysMng/Role'
- import Menu from '@/views/SysMng/Menu'
- import Log from '@/views/SysMng/Log'
- Vue.use(Router)
- const router = new Router({
- routes: [
- {
- path: '/',
- name: '首页',
- component: Home,
- children: [
- { path: '', component: Intro, name: '系统介绍' },
- { path: '/user', component: User, name: '用户管理' },
- { path: '/dept', component: Dept, name: '机构管理' },
- { path: '/role', component: Role, name: '角色管理' },
- { path: '/menu', component: Menu, name: '菜单管理' },
- { path: '/log', component: Log, name: '日志管理' }
- ]
- },
- {
- path: '/login',
- name: '登录',
- component: Login
- }
- ,{
- path: '/404',
- name: 'notFound',
- component: NotFound
- }
- ]
- })
- 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
测试效果
封装重构之后,启动界面,效果跟之前差别不大。
源码下载
后端:https://gitee.com/liuge1988/kitty
前端:https://gitee.com/liuge1988/kitty-ui.git
作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/
版权所有,欢迎转载,转载请注明原文作者及出处。
Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装的更多相关文章
- Vue + Element UI 实现权限管理系统 前端篇(十三):页面权限控制
权限控制方案 既然是后台权限管理系统,当然少不了权限控制啦,至于权限控制,前端方面当然就是对页面资源的访问和操作控制啦. 前端资源权限主要又分为两个部分,即导航菜单的查看权限和页面增删改操作按钮的操作 ...
- Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块
用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口. import axios from '../axios' /* * 用户管理模块 */ // 保存 exp ...
- Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库
使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...
- Vue + Element UI 实现权限管理系统 前端篇(八):管理应用状态
使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...
- Vue + Element UI 实现权限管理系统 前端篇(六):更换皮肤主题
自定义主题 命令行主题工具 1.安装主题工具 首先安装「主题生成工具」,可以全局安装或者安装在当前项目下,推荐安装在项目里,方便别人 clone 项目时能直接安装依赖并启动. yarn add ele ...
- Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境
技术基础 开发之前,请先熟悉下面的4个文档 vue.js2.0中文, 优秀的JS框架 vue-router, vue.js 配套路由 vuex,vue.js 应用状态管理库 Element,饿了么提供 ...
- Vue + Element UI 实现权限管理系统 前端篇(十六):系统备份还原
系统备份还原 在很多时候,我们需要系统数据进行备份还原.我们这里就使用MySql的备份还原命令实现系统备份还原的功能. 后台接口准备 系统备份还原是对数据库的备份还原,所以必须有后台接口的支持,我们准 ...
- Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单
动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...
- Vue + Element UI 实现权限管理系统 前端篇(四):优化登录流程
完善登录流程 1. 丰富登录界面 1.1 从 Element 指南中选择组件模板丰富登录界面,放置一个登录界面表单,包含账号密码输入框和登录重置按钮. <template> <el- ...
随机推荐
- js基础学习笔记(零七)
indexOf() 方法 返回某个指定的字符串值在字符串中首次出现的位置. 语法: stringObject.indexOf(substring, startpos) 参数说明: 注意:如果要检索的字 ...
- springboot工程读取配置文件application.yml的写法18045
现在流行springboot框架的项目,里面的默认配置文件为application.yml,我们怎样读取这个配置文件呢? 先贴上我得配置文件吧 目录结构 里面内容 1 写读取配置文件的工具类 @Con ...
- Java中方法重写和方法重载
首先方法重写和方法重载是建立在Java的面向对象的继承和多态的特性基础上而出现的.至于面向对象的继承和多态的特性我就不在这里多说了.继承是指在一个父类的基础再创建一个子类,这样子类就拥有了父类的非私 ...
- bootstrap增删改查
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...
- Maven中项目的启动
在run选项卡中,选择Run Configurations
- SharePoint 列表中增加列编辑功能菜单
需求描述 在企业的部署中,经常将SharePoint和TFS集成在一起,两个系统之间相互读取数据,展现开发进度.在TFS 2018之前版本中,由于TFS的门户定制功能有限,用户比较喜欢使用ShareP ...
- mysql rand
在where语句中,rand有时候会出现多条记录
- Android-----application的学习
一.Application的对象回调函数 1.onCreate : Application对象被创建时候会调用 2.onConfigurationChanged : 屏幕方向变化.系统语言的更改等 3 ...
- C#6.0语言规范(十三) 接口
接口定义合同.实现接口的类或结构必须遵守其合同.接口可以从多个基接口继承,并且类或结构可以实现多个接口. 接口可以包含方法,属性,事件和索引器.接口本身不为它定义的成员提供实现.接口仅指定必须由实现接 ...
- 【TensorFlow】:解决TensorFlow的ImportError: DLL load failed: 动态链接库(DLL)初始化例程失败
[背景] 在scikit-learn基础上系统结合数学和编程的角度学习了机器学习后(我的github:https://github.com/wwcom614/machine-learning),意犹未 ...