zoukankan      html  css  js  c++  java
  • 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 {
                 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="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 {
             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="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;

    显示效果

  • 相关阅读:
    【HTTP】一、HTTP协议简介及其工作流程
    【总结】计算机网络常见问题
    【LeetCode】714、买卖股票的最佳时机含手续费
    【LeetCode】309、最佳买卖股票时机含冷冻期
    【LeetCode】188、买卖股票的最佳时机 IV
    【LeetCode】123、买卖股票的最佳时机 III
    【LeetCode】122、买卖股票的最佳时机 II
    【LeetCode】121、买卖股票的最佳时机
    windows搭建测试环境
    css 和常用快捷键
  • 原文地址:https://www.cnblogs.com/CZheng7/p/13418961.html
Copyright © 2011-2022 走看看