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

测试效果
封装重构之后,启动界面,效果跟之前差别不大。
Vue + Element UI 实现权限管理系统 (功能组件封装)的更多相关文章
- Vue + Element UI 实现权限管理系统
Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境 https://www.cnblogs.com/xifengxiaoma/p/9533018.html
- Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装
组件封装 为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度. 组件结构 组件封装重构后,试图组件结构如下图所示 代码一览 Home组件被简化,包含导航.头部和主内容三个组 ...
- Vue + Element UI 实现权限管理系统 前端篇(十三):页面权限控制
权限控制方案 既然是后台权限管理系统,当然少不了权限控制啦,至于权限控制,前端方面当然就是对页面资源的访问和操作控制啦. 前端资源权限主要又分为两个部分,即导航菜单的查看权限和页面增删改操作按钮的操作 ...
- Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块
用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口. import axios from '../axios' /* * 用户管理模块 */ // 保存 exp ...
- Vue + Element UI 实现权限管理系统 (管理应用状态)
使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...
- Vue + Element UI 实现权限管理系统 前端篇(八):管理应用状态
使用 Vuex 管理应用状态 1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题.收缩 ...
- Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库
使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...
- Vue + Element UI 实现权限管理系统(第三方图标库)
使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...
- Vue + Element UI 实现权限管理系统 前端篇(十四):菜单功能实现
菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作. 提供一个菜单查询接口,查询整颗菜单树形结构. http/modules/menu.js 添加 findMenuTree 接口. ...
随机推荐
- Given d and e, factorize N to attack RSA
题目如下: RSA算法的使用一般要求每个不同的用户有一个独立的模数N.有天,Bob脑洞大开,认为似乎没有必要这样做.只需要一个模数N,然后给不同的用户分发不同的e和d就好了.可惜这种做法有严重的安全漏 ...
- Android requestCode的限制
一. why ? 由于才疏学浅,在开发中requestCode的让我很困惑.困惑是因为什么呢,是因为弄混了.要想弄明白,不困惑,来想一想用到requestCode的地方: ① startActivit ...
- List、Map、Set的区别与联系
重复和有序 List 存储的元素是有顺序的,并且值允许重复: Map 元素按键值对存储,无放入顺序 ,它的键是不允许重复的,但是值是允许重复的: Set 存储的元素是无顺序的,并且不允许重复,元素虽然 ...
- 使用VSCode如何从github拉取项目
转载自:https://blog.csdn.net/sunqy1995/article/details/81517159 1.开vscode使用CTRL+`或者点击查看到集成终端打开控制终端 2. 在 ...
- winfrom 动态添加控件,以及删除
private void btnadd_Click(object sender, EventArgs e) { int fileCount = 0; ...
- 解码字符串 Decode String
2018-11-14 17:56:12 问题描述: 问题求解: 方法一.递归求解 最直观的解法就是递归来求了,并且很显然的这个问题可以使用递归来进行求解. public String decodeSt ...
- php递归方法
<?phpheader("Content-type:text/html;charset=utf-8");$city=array( array('id'=>1,'name ...
- Spring Boot入门第三天:配置日志系统和Druid数据库连接池。
原文链接 一.日志管理 1.在application.properties文件中加入如下内容: logging.level.root=WARN logging.level.org.springfram ...
- You Don't Know JS: Scope & Closures (第4章: Hoisting)
Chapter4: Hoisting 变量附加到哪个层次的scope,由它们在哪里和如何声明(let, var)来决定. Function scope/Block scope都有相同的法则:任何变量在 ...
- 通过.frm和.ibd恢复mysql数据
.frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索 ...