Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装

摘要:
如果您感兴趣,您可以访问原作者的网站Vue+ElementUI来实现权限管理系统的前端(VI):皮肤替换主题Vue+Element UI来实现许可管理系统的后端(V.组件封装模块化,以提高后期组件结构的可维护性Home.Vue<template><divclass=“container”˃importHeaderBar from'/标题栏/标题栏;importMenuBarfrom'/菜单栏/菜单栏';importMainCfrom'./Main/Main'导出默认{components:{HeaderBar,MenuBar,MainC}}.container{position:absolute;top:0;bottom:0;left:0;right:0;background:#4b5f6e;}标题栏。vue<template><divclass=“header container”><!--icon@click.prevent:阻止默认行为--˃Home消息中心订单管理注销importmockfrom“@/lock/index.js”;exportdefault{data(){return{isCollapse:false,用户名:“Louis”,userAvatar:“”,activeIndex:'1'};},方法:{selectNavBar{console.log},//折叠导航栏Collapse:function(){this.isCollapse=!this.isCollapse;}//退出登录注销:function(){var_this=this;this.$confirm(“您确定要退出吗?

因为我暂时不需要第五章和第六章教程的内容所以直接进入第七章。感兴趣的可以访问原作者网站


注:本次封装的css样式应该有点问题,但考虑时间问题没有认真修改,后续有时间重构时候补上。

组件封装

模块化,提升后期的可维护性

组件结构

Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装第1张

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   @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   trigger="hover">
                <span class="el-dropdown-link userinfo-inner">
                    <img :src="http://t.zoukankan.com/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="isCollapse?'menu-bar-collapse-width':'menu-bar-width'">
            <img :src="http://t.zoukankan.com/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="http://t.zoukankan.com/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;

显示效果

Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装第2张

免责声明:文章转载自《Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ORACLE中常见的几种锁从零开始手写 dubbo rpc 框架下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

浅析vue实例的生命周期(生命周期钩子)

“每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等” ,在不同的生命周期内会经历不同的钩子函数(生命周期函数),这就提供了将我们自己的代码写入的机会。如果将生命周期比作人的话,生命周期就是一个人的一生,生命钩子函数就相当于人的不同年龄段(幼年、青年、中年、老年)...

Vue之项目搭建

  一、Vue自动化工具的安装 nvm:nodejs 版本管理工具。 也就是说:一个 nvm 可以管理很多 node 版本和 npm 版本。 nodejs:在项目开发时的所需要的代码库 npm:nodejs 包管理工具。 在安装的 nodejs 的时候,npm 也会跟着一起安装,它是包管理工具。 npm 管理 nodejs 中的第三方插件   1,安装nv...

layui学习--tab选项卡

var element; var $; layui.use(['element','jquery'],function(){ element = layui.element, $ = layui.jquery; //监听左侧菜单点击 element.on('nav(left-menu)', function(elem){...

Vue 多环境配置方法

开发应用时环境有开发环境、测试环境、生产环境等,此时我们需要配置不同的环境,获取不同的apiUrl前缀,避免了频繁手动更改api. 1.安装cross-env插件 cross-env是跨平台设置和使用环境变量的脚本。在大多数Windows命令行中在使用NODE_ENV = production设置环境变量时会报错。同样,Windows和Linux命令如何...

JS DOM元素

// 为element增加一个样式名为newClassName的新样式 functionaddClass(element, newClassName) { var value =element.className; element.className = value + " " +newClassName; } var bo...

logic:iterate 遍历

1. 遍历集合 <logic:iterate> 的 name 属性指定需要进行遍历的集合对象, 它每次从集合中检索出一个元素, 然后把它放在page 范围内, 并以id 属性指定的字符串来命名这个元素, 例如: <% Vector animals = new Vector(); animals.addElement("Dog"); ani...