组件封装

为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度。

组件结构

组件封装重构后,试图组件结构如下图所示

代码一览

Home组件被简化,包含导航、头部和主内容三个组件。

Home.vue

  1. <template>
  2. <div class="container">
  3. <!-- 导航菜单栏 -->
  4. <MenuBar></MenuBar>
  5. <!-- 头部区域 -->
  6. <HeadBar></HeadBar>
  7. <!-- 主内容区域 -->
  8. <Main></Main>
  9. </div>
  10. </template>
  11.  
  12. <script>
  13. import HeadBar from "./HeadBar/HeadBar"
  14. import MenuBar from "./MenuBar/MenuBar"
  15. import Main from "./Main/Main"
  16. export default {
  17. components:{
  18. HeadBar,
  19. MenuBar,
  20. Main
  21. }
  22. };
  23. </script>
  24.  
  25. <style scoped lang="scss">
  26. .container {
  27. position:absolute;
  28. top: 0px;
  29. left: 0px;
  30. right: 0px;
  31. background: #4b5f6e;
  32. }
  33. </style>

HeadBar.vue

  1. <template>
  2. <div class="container">
  3. <!-- 导航菜单隐藏显示切换 -->
  4. <span class="collapse-switcher" @click.prevent="collapse">
  5. <i class="el-icon-menu"></i>
  6. </span>
  7. <!-- 导航菜单 -->
  8. <span class="nav-bar">
  9. <el-menu :default-active="activeIndex" class="el-menu-demo" text-color="#fff"
  10. active-text-color="#ffd04b" mode="horizontal" @select="selectNavBar()">
  11. <el-menu-item index="1" @click="$router.push('/')">{{$t("common.home")}}</el-menu-item>
  12. <el-menu-item index="2">{{$t("common.doc")}}</el-menu-item>
  13. <el-menu-item index="3">{{$t("common.msgCenter")}}</el-menu-item>
  14. </el-menu>
  15. </span>
  16. <span class="tool-bar">
  17. <!-- 主题切换 -->
  18. <ThemePicker class="theme-picker"></ThemePicker>
  19. <!-- 语言切换 -->
  20. <LangSelector class="lang-selector"></LangSelector>
  21. <!-- 用户信息 -->
  22. <el-dropdown class="user-info-dropdown" trigger="hover">
  23. <span class="el-dropdown-link"><img :src="this.userAvatar" /> {{username}}</span>
  24. <el-dropdown-menu slot="dropdown">
  25. <el-dropdown-item>{{$t("common.myMsg")}}</el-dropdown-item>
  26. <el-dropdown-item>{{$t("common.config")}}</el-dropdown-item>
  27. <el-dropdown-item divided @click.native="logout">{{$t("common.logout")}}</el-dropdown-item>
  28. </el-dropdown-menu>
  29. </el-dropdown>
  30. </span>
  31. </div>
  32. </template>
  33.  
  34. <script>
  35. import mock from "@/mock/index.js";
  36. import ThemePicker from "@/components/ThemePicker"
  37. import LangSelector from "@/components/LangSelector"
  38. export default {
  39. components:{
  40. ThemePicker,
  41. LangSelector
  42. },
  43. data() {
  44. return {
  45. isCollapse: false,
  46. username: "Louis",
  47. userAvatar: "",
  48. activeIndex: '1'
  49. };
  50. },
  51. methods: {
  52. selectNavBar(key, keyPath) {
  53. console.log(key, keyPath)
  54. },
  55. // 语言切换
  56. handleCommand(command) {
  57. let array = command.split(':')
  58. let lang = array[0] === '' ? 'zh_cn' : array[0]
  59. let label = array[1]
  60. document.getElementById("language").innerHTML = label
  61. this.$i18n.locale = lang
  62. },
  63. //折叠导航栏
  64. collapse: function() {
  65. this.isCollapse = !this.isCollapse;
  66. },
  67. //退出登录
  68. logout: function() {
  69. var _this = this;
  70. this.$confirm("确认退出吗?", "提示", {
  71. type: "warning"
  72. })
  73. .then(() => {
  74. sessionStorage.removeItem("user");
  75. this.$router.push
  76. ("/login");
  77. })
  78. .catch(() => {});
  79. }
  80. },
  81. mounted() {
  82. this.sysName = "I like Kitty";
  83. var user = sessionStorage.getItem("user");
  84. if (user) {
  85. this.userName = user;
  86. this.userAvatar = require("@/assets/user.png");
  87. }
  88. }
  89. };
  90. </script>
  91.  
  92. <style scoped lang="scss">
  93. .container {
  94. position: absolute;
  95. left: 200px;
  96. right: 0px;
  97. height: 60px;
  98. line-height: 60px;
  99. .collapse-switcher {
  100. width: 40px;
  101. float: left;
  102. cursor: pointer;
  103. border-color: rgba(111, 123, 131, 0.8);
  104. border-left-width: 1px;
  105. border-left-style: solid;
  106. border-right-width: 1px;
  107. border-right-style: solid;
  108. color: white;
  109. background: #504e6180;
  110. }
  111. .nav-bar {
  112. margin-left: auto;
  113. float: left;
  114. .el-menu {
  115. background: #504e6180;
  116. }
  117. }
  118. .tool-bar {
  119. float: right;
  120. .theme-picker {
  121. padding-right: 10px;
  122. }
  123. .lang-selector {
  124. padding-right: 10px;
  125. font-size: 15px;
  126. color: #fff;
  127. cursor: pointer;
  128. }
  129. .user-info-dropdown {
  130. font-size: 20px;
  131. padding-right: 20px;
  132. color: #fff;
  133. cursor: pointer;
  134. img {
  135. width: 40px;
  136. height: 40px;
  137. border-radius: 10px;
  138. margin: 10px 0px 10px 10px;
  139. float: right;
  140. }
  141. }
  142. }
  143. }
  144. </style>

MenuBar.vue

  1. <template>
  2. <div class="menu-bar-container">
  3. <!-- logo -->
  4. <div class="logo" :class="isCollapse?'menu-bar-collapse-width':'menu-bar-width'">
  5. <img :src="this.logo" /> <div>{{isCollapse?'':sysName}}</div>
  6. </div>
  7. <!-- 导航菜单 -->
  8. <el-menu default-active="1-1" :class="isCollapse?'menu-bar-collapse-width':'menu-bar-width'" @open="handleopen" @close="handleclose" @select="handleselect" :collapse="isCollapse">
  9. <el-submenu index="1">
  10. <template slot="title">
  11. <i class="el-icon-location"></i>
  12. <span slot="title">{{$t("sys.sysMng")}}</span>
  13. </template>
  14. <el-menu-item index="1-1" @click="$router.push('user')">{{$t("sys.userMng")}}</el-menu-item>
  15. <el-menu-item index="1-2" @click="$router.push('dept')">{{$t("sys.deptMng")}}</el-menu-item>
  16. <el-menu-item index="1-3" @click="$router.push('role')">{{$t("sys.roleMng")}}</el-menu-item>
  17. <el-menu-item index="1-4" @click="$router.push('menu')">{{$t("sys.menuMng")}}</el-menu-item>
  18. <el-menu-item index="1-5" @click="$router.push('log')">{{$t("sys.logMng")}}</el-menu-item>
  19. </el-submenu>
  20. <el-submenu index="2">
  21. <template slot="title">
  22. <i class="el-icon-location"></i>
  23. <span slot="title">{{$t("sys.sysMonitor")}}</span>
  24. </template>
  25. </el-submenu>
  26. <el-menu-item index="3" disabled>
  27. <i class="el-icon-document"></i>
  28. <span slot="title">{{$t("sys.nav3")}}</span>
  29. </el-menu-item>
  30. <el-menu-item index="4">
  31. <i class="el-icon-setting"></i>
  32. <span slot="title">{{$t("sys.nv4")}}</span>
  33. </el-menu-item>
  34. </el-menu>
  35. </div>
  36. </template>
  37.  
  38. <script>
  39. export default {
  40. data() {
  41. return {
  42. isCollapse: false,
  43. sysName: "",
  44. logo: "",
  45. };
  46. },
  47. methods: {
  48. handleopen() {
  49. console.log('handleopen');
  50. },
  51. handleclose() {
  52. console.log('handleclose');
  53. },
  54. handleselect(a, b) {
  55. console.log('handleselect');
  56. }
  57. },
  58. mounted() {
  59. this.sysName = "I like Kitty";
  60. this.logo = require("@/assets/logo.png");
  61. }
  62. };
  63. </script>
  64.  
  65. <style scoped lang="scss">
  66. .menu-bar-container {
  67. .el-menu {
  68. position:absolute;
  69. top: 60px;
  70. bottom: 0px;
  71. text-align: left;
  72. }
  73. .logo {
  74. position:absolute;
  75. top: 0px;
  76. height: 60px;
  77. line-height: 60px;
  78. background: #4b5f6e;
  79. img {
  80. width: 40px;
  81. height: 40px;
  82. border-radius: 0px;
  83. margin: 10px 10px 10px 10px;
  84. float: left;
  85. }
  86. div {
  87. font-size: 22px;
  88. color: white;
  89. text-align: left;
  90. }
  91. }
  92. .menu-bar-width {
  93. width: 200px;
  94. }
  95. .menu-bar-collapse-width {
  96. width: 65px;
  97. }
  98. }
  99. </style>

Main.vue

  1. <template>
  2. <div class="container">
  3. <el-breadcrumb separator="/" class="breadcrumb">
  4. <el-breadcrumb-item v-for="item in $route.matched" :key="item.path">
  5. <a href="www.baidu.com">{{ item.name }}</a>
  6. </el-breadcrumb-item>
  7. </el-breadcrumb>
  8. <transition name="fade" mode="out-in">
  9. <router-view></router-view>
  10. </transition>
  11. </div>
  12. </template>
  13.  
  14. <script>
  15. export default {
  16. data() {
  17. return {
  18. };
  19. },
  20. methods: {
  21.  
  22. },
  23. mounted() {
  24.  
  25. }
  26. };
  27. </script>
  28.  
  29. <style scoped lang="scss">
  30. .container {
  31. position: absolute;
  32. top: 60px;
  33. bottom: 0px;
  34. left: 200px;
  35. right: 0px;
  36. .breadcrumb {
  37. padding: 10px;
  38. border-color: rgba(38, 86, 114, 0.2);
  39. border-bottom-width: 1px;
  40. border-bottom-style: solid;
  41. background: rgba(138, 158, 170, 0.2);
  42. }
  43. }
  44. </style>

国际化语言切换也被封装成为了组件 LangSelector

LangSelector/index.js

  1. <template>
  2. <el-dropdown class="lang-selector" @command="handleCommand">
  3. <span class="el-dropdown-link">
  4. <span id="language">中文</span><i class="el-icon-arrow-down el-icon--right"></i>
  5. </span>
  6. <el-dropdown-menu slot="dropdown">
  7. <el-dropdown-item command="zh_cn:中文">中文</el-dropdown-item>
  8. <el-dropdown-item command="en_us:English">English</el-dropdown-item>
  9. </el-dropdown-menu>
  10. </el-dropdown>
  11. </template>
  12.  
  13. <script>
  14. export default {
  15. methods: {
  16. // 语言切换
  17. handleCommand(command) {
  18. let array = command.split(':')
  19. let lang = array[0] === '' ? 'zh_cn' : array[0]
  20. let label = array[1]
  21. document.getElementById("language").innerHTML = label
  22. this.$i18n.locale = lang
  23. }
  24. }
  25. }
  26. </script>

组件封装重构之后,同步修改路由配置

  1. import Vue from 'vue'
  2. import Router from 'vue-router'
  3. import Login from '@/views/Login'
  4. import NotFound from '@/views/404'
  5. import Home from '@/views/Home'
  6. import Intro from '@/views/Intro'
  7. import User from '@/views/SysMng/User'
  8. import Dept from '@/views/SysMng/Dept'
  9. import Role from '@/views/SysMng/Role'
  10. import Menu from '@/views/SysMng/Menu'
  11. import Log from '@/views/SysMng/Log'
  12.  
  13. Vue.use(Router)
  14.  
  15. const router = new Router({
  16. routes: [
  17. {
  18. path: '/',
  19. name: '首页',
  20. component: Home,
  21. children: [
  22. { path: '', component: Intro, name: '系统介绍' },
  23. { path: '/user', component: User, name: '用户管理' },
  24. { path: '/dept', component: Dept, name: '机构管理' },
  25. { path: '/role', component: Role, name: '角色管理' },
  26. { path: '/menu', component: Menu, name: '菜单管理' },
  27. { path: '/log', component: Log, name: '日志管理' }
  28. ]
  29. },
  30. {
  31. path: '/login',
  32. name: '登录',
  33. component: Login
  34. }
  35. ,{
  36. path: '/404',
  37. name: 'notFound',
  38. component: NotFound
  39. }
  40. ]
  41. })
  42.  
  43. router.beforeEach((to, from, next) => {
  44. // 登录界面登录成功之后,会把用户信息保存在会话
  45. // 存在时间为会话生命周期,页面关闭即失效。
  46. let user = sessionStorage.getItem('user');
  47. if (to.path == '/login') {
  48. // 如果是访问登录界面,如果用户会话信息存在,代表已登录过,跳转到主页
  49. if(user) {
  50. next({ path: '/' })
  51. } else {
  52. next()
  53. }
  54. } else {
  55. // 如果访问非登录界面,且户会话信息不存在,代表未登录,则跳转到登录界面
  56. if (!user) {
  57. next({ path: '/login' })
  58. } else {
  59. next()
  60. }
  61. }
  62. })
  63.  
  64. export default router

测试效果

封装重构之后,启动界面,效果跟之前差别不大。

源码下载

后端:https://gitee.com/liuge1988/kitty

前端:https://gitee.com/liuge1988/kitty-ui.git


作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/
版权所有,欢迎转载,转载请注明原文作者及出处。

Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装的更多相关文章

  1. Vue + Element UI 实现权限管理系统 前端篇(十三):页面权限控制

    权限控制方案 既然是后台权限管理系统,当然少不了权限控制啦,至于权限控制,前端方面当然就是对页面资源的访问和操作控制啦. 前端资源权限主要又分为两个部分,即导航菜单的查看权限和页面增删改操作按钮的操作 ...

  2. Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块

    用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口. import axios from '../axios' /* * 用户管理模块 */ // 保存 exp ...

  3. Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库

    使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...

  4. Vue + Element UI 实现权限管理系统 前端篇(八):管理应用状态

    使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...

  5. Vue + Element UI 实现权限管理系统 前端篇(六):更换皮肤主题

    自定义主题 命令行主题工具 1.安装主题工具 首先安装「主题生成工具」,可以全局安装或者安装在当前项目下,推荐安装在项目里,方便别人 clone 项目时能直接安装依赖并启动. yarn add ele ...

  6. Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境

    技术基础 开发之前,请先熟悉下面的4个文档 vue.js2.0中文, 优秀的JS框架 vue-router, vue.js 配套路由 vuex,vue.js 应用状态管理库 Element,饿了么提供 ...

  7. Vue + Element UI 实现权限管理系统 前端篇(十六):系统备份还原

    系统备份还原 在很多时候,我们需要系统数据进行备份还原.我们这里就使用MySql的备份还原命令实现系统备份还原的功能. 后台接口准备 系统备份还原是对数据库的备份还原,所以必须有后台接口的支持,我们准 ...

  8. Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  9. Vue + Element UI 实现权限管理系统 前端篇(四):优化登录流程

    完善登录流程 1. 丰富登录界面 1.1 从 Element 指南中选择组件模板丰富登录界面,放置一个登录界面表单,包含账号密码输入框和登录重置按钮. <template> <el- ...

随机推荐

  1. js基础学习笔记(零七)

    indexOf() 方法 返回某个指定的字符串值在字符串中首次出现的位置. 语法: stringObject.indexOf(substring, startpos) 参数说明: 注意:如果要检索的字 ...

  2. springboot工程读取配置文件application.yml的写法18045

    现在流行springboot框架的项目,里面的默认配置文件为application.yml,我们怎样读取这个配置文件呢? 先贴上我得配置文件吧 目录结构 里面内容 1 写读取配置文件的工具类 @Con ...

  3. Java中方法重写和方法重载

     首先方法重写和方法重载是建立在Java的面向对象的继承和多态的特性基础上而出现的.至于面向对象的继承和多态的特性我就不在这里多说了.继承是指在一个父类的基础再创建一个子类,这样子类就拥有了父类的非私 ...

  4. bootstrap增删改查

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  5. Maven中项目的启动

    在run选项卡中,选择Run Configurations

  6. SharePoint 列表中增加列编辑功能菜单

    需求描述 在企业的部署中,经常将SharePoint和TFS集成在一起,两个系统之间相互读取数据,展现开发进度.在TFS 2018之前版本中,由于TFS的门户定制功能有限,用户比较喜欢使用ShareP ...

  7. mysql rand

    在where语句中,rand有时候会出现多条记录

  8. Android-----application的学习

    一.Application的对象回调函数 1.onCreate : Application对象被创建时候会调用 2.onConfigurationChanged : 屏幕方向变化.系统语言的更改等 3 ...

  9. C#6.0语言规范(十三) 接口

    接口定义合同.实现接口的类或结构必须遵守其合同.接口可以从多个基接口继承,并且类或结构可以实现多个接口. 接口可以包含方法,属性,事件和索引器.接口本身不为它定义的成员提供实现.接口仅指定必须由实现接 ...

  10. 【TensorFlow】:解决TensorFlow的ImportError: DLL load failed: 动态链接库(DLL)初始化例程失败

    [背景] 在scikit-learn基础上系统结合数学和编程的角度学习了机器学习后(我的github:https://github.com/wwcom614/machine-learning),意犹未 ...