美文网首页
(二)vue + element UI 搭建后台管理导航菜单

(二)vue + element UI 搭建后台管理导航菜单

作者: 走走婷婷1215 | 来源:发表于2018-01-30 16:31 被阅读15551次

    上篇文章:https://www.jianshu.com/p/c674be93bdd6
    在上篇的基础上进行延伸,搭建出一个简单的可折叠的后台管理导航菜单
    界面如下:

    后台管理系统.png
    项目结构:
    项目结构.png
    具体实现代码如下:
    index.html
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>后台管理系统</title>
    </head>
    
    <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    </body>
    
    </html>
    

    main.js

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    //ElementUI
    import ElementUI from 'element-ui'
    
    import './assets/theme/element-#36B42A/index.css'
    
    import 'font-awesome/css/font-awesome.min.css'
    
    
    Vue.config.productionTip = false
    
    Vue.use(ElementUI)
    
    import axios from 'axios'
    Vue.prototype.$axios = axios
    axios.interceptors.response.use(res => {
        if (!res.data)
            return res
        if (!res.data.errorCode || res.data.errorCode != 302)
            return res
        sessionStorage.removeItem('user')
        location.reload()
        return res
    })
    
    /* eslint-disable no-new */
    new Vue({
        el: '#app',
        router,
        template: '<App/>',
        components: {
            App
        }
    
    })
    
    

    App.vue

    <template>
        <div id="app">
            <transition name="fade" mode="out-in">
                <router-view></router-view>
            </transition>
        </div>
    </template>
    
    <script>
        export default {
            name: 'app',
            components: {}
        }
    </script>
    
    <style lang="scss">
        body {
            margin: 0;
            padding: 0;
            font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
            font-size: 14px;
            -webkit-font-smoothing: antialiased;
        }
    
        #app {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    
        .el-submenu [class^=fa] {
            vertical-align: baseline;
            margin-right: 10px;
        }
    
        .el-menu-item [class^=fa] {
            vertical-align: baseline;
            margin-right: 10px;
        }
    
        .toolbar {
            background: #f2f2f2;
            padding: 10px;
            margin: 10px 0;
        .el-form-item {
            margin-bottom: 10px;
        }
        }
    
        .fade-enter-active,
        .fade-leave-active {
            transition: all 0.2s ease;
        }
    
        .fade-enter,
        .fade-leave-active {
            opacity: 0;
        }
    </style>
    
    

    路由中的代码:
    router/index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    
    import Dashboard from '@/components/Dashboard'
    import Main from '@/components/Main'
    
    
    
    Vue.use(Router)
    
    let routes = [{
        path:'/',
        component: Main,
        hidden: true,
        children: [{
            path: '/',
            component:Dashboard,
            name:'首页'
        }]
    }]
    
    import {
        SystemRouter
    } from './system'
    
    for (let i in SystemRouter){
        routes.push(SystemRouter[i])
    }
    
    const router = new Router({
        routes: routes
    })
    
    export default router;
    
    

    router/system.js

    import Main from '@/components/Main'
    import Contract from '@/components/system/Contract'
    
    const SystemRouter = [{
        path: '/system',
        name: '系统中心',
        component: Main,
        iconCls: 'fa fa-address-card',
        children: [{
            path: '/system/contract',
            component: Contract,
            name: '联系人管理'
        }]
    }]
    
    export {
        SystemRouter
    }
    

    components/Main.vue

    <template>
        <el-row class="container">
            <el-col :span="24" class="header">
                <el-col :span="5" class="logo" :class="'logo-width'">
                    <a href="/" style="text-decoration:none;color:#FFFFFF;">
                        后台管理系统
                    </a>
                </el-col>
                <el-col :span="2">
                    <div class="tools" @click.prevent="collapse">
                        <i class="fa fa-align-justify"></i>
                    </div>
                </el-col>
                <el-col :span="10" class="userinfo">
                    <el-dropdown trigger="hover">
                        <span class="el-dropdown-link userinfo-inner">
                            你好:管理员
                        </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item>
                                <a href="#/">首页</a>
                            </el-dropdown-item>
                            <el-dropdown-item>
                                <a @click="">修改密码</a>
                            </el-dropdown-item>
                            <el-dropdown-item @click.native="">
                                注销登录
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </el-col>
            </el-col>
            <el-col :span="24" class="main">
                <aside :class="collapsed?'menu-collapsed':'menu-expanded'">
                    <!--导航菜单-->
                    <el-menu background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" v-bind:style=" collapsed ? {} : { 'width': '230px' } " :default-active="$route.path" class="el-menu-vertical-demo" unique-opened router v-show="!collapsed">
                        <template v-for="(item,index) in menuData" v-if="!item.hidden">
                            <el-submenu :index="index+''" v-if="!item.leaf">
                                <template slot="title">
                                    <i :class="item.iconCls"></i>{{item.name}}
                                </template>
                                <el-menu-item v-for="child in item.children" :index="child.path" :key="child.path" v-if="!child.hidden">
                                    {{child.name}}
                                </el-menu-item>
                            </el-submenu>
                            <el-menu-item v-if="item.leaf&&item.children.length>0" :index="item.children[0].path">
                                <i :class="item.iconCls"></i>{{item.children[0].name}}
                            </el-menu-item>
                        </template>
                    </el-menu>
                    <!--导航菜单-折叠后-->
                    <ul class="el-menu el-menu-vertical-demo collapsed el-menu-collapsed" v-show="collapsed" ref="menuCollapsed">
                        <li v-for="(item,index) in menuData" v-if="!item.hidden" class="el-submenu item">
                            <template v-if="!item.leaf">
                                <div class="el-submenu__title" style="padding-left: 20px;" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)">
                                    <i :class="item.iconCls"></i>
                                </div>
                                <ul class="el-menu submenu" :class="'submenu-hook-'+index" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)">
                                    <li v-for="child in item.children" v-if="!child.hidden" :key="child.path" class="el-menu-item" style="padding-left: 40px; color: #fff;" :class="$route.path==child.path?'is-active':''" @click="$router.push(child.path)">
                                        {{child.name}}
                                    </li>
                                </ul>
                            </template>
                            <template v-else>
                                <li class="el-submenu">
                                    <div class="el-submenu__title el-menu-item" style="padding-left: 20px;height: 56px;line-height: 56px;padding: 0 20px;" :class="$route.path==item.children[0].path?'is-active':''" @click="$router.push(item.children[0].path)">
                                        <i :class="item.iconCls"></i>
                                    </div>
                                </li>
                            </template>
                        </li>
                    </ul>
                </aside>
                <section class="content-container">
                    <div class="grid-content bg-purple-light">
                        <el-col :span="24" class="breadcrumb-container">
                            <strong class="title">{{$route.name}}</strong>
                            <el-breadcrumb separator="/" class="breadcrumb-inner">
                                <el-breadcrumb-item v-for="item in $route.matched" :key="item.path">
                                    {{ item.name }}
                                </el-breadcrumb-item>
                            </el-breadcrumb>
                        </el-col>
                        <el-col :span="24" class="content-wrapper">
                            <transition name="fade" mode="out-in">
                                <router-view></router-view>
                            </transition>
                        </el-col>
                    </div>
                </section>
            </el-col>
    
        </el-row>
    </template>
    
    <script>
        
        let data = () => {
            return {
                sysName: '后台管理系统',
                menuData: [],
                collapsed: false,
                sysUserName: '管理员',
            }
        }
    
        let initMenu = function() {
            for(let i in this.$router.options.routes) {
                let root = this.$router.options.routes[i]
                if(root.hidden)
                    continue
                let children = []
                for(let j in root.children) {
                    let item = root.children[j]
                    if(item.hidden)
                        continue
                    children.push(item)
                }
    
                if(children.length < 1)
                    continue
                this.menuData.push(root)
                root.children = children
            }
        }
    
        export default {
            data: data,
            methods: {
                initMenu: initMenu,
                //折叠导航栏
                collapse: function() {
                    this.collapsed = !this.collapsed;
                },
                showMenu: function(i, status) {
                    this.$refs.menuCollapsed.getElementsByClassName('submenu-hook-' + i)[0].style.display = status ? 'block' : 'none';
                }
            },
            mounted: function() {
                this.initMenu()
            }
        }
    </script>
    
    <style scoped="scoped" lang="scss">
        .container {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
            .header {
                height: 60px;
                line-height: 60px;
                background: #545c64;
                color: #fff;
                .userinfo {
                    text-align: right;
                    padding-right: 35px;
                    float: right;
                    .userinfo-inner {
                        cursor: pointer;
                        color: #fff;
                        img {
                            width: 40px;
                            height: 40px;
                            border-radius: 20px;
                            margin: 10px 0 10px 10px;
                            float: right;
                        }
                    }
                }
                .logo {
                    height: 60px;
                    font-size: 22px;
                    padding-left: 20px;
                    padding-right: 20px;
                    border-color: rgba(238, 241, 146, 0.3);
                    border-right-width: 1px;
                    border-right-style: solid;
                    img {
                        width: 40px;
                        float: left;
                        margin: 10px 10px 10px 18px;
                    }
                    .txt {
                        color: #fff;
                    }
                }
                .logo-width {
                    width: 230px;
                }
                .logo-collapse-width {
                    width: 60px;
                }
                .tools {
                    padding: 0 23px;
                    width: 14px;
                    height: 60px;
                    line-height: 60px;
                    cursor: pointer;
                }
            }
            .main {
                display: flex;
                position: absolute;
                top: 60px;
                bottom: 0;
                overflow: hidden;
                aside {
                    flex: 0 0 230px;
                    width: 230px;
                    /*侧边菜单*/
                    .el-menu {
                        height: 100%;
                        background-color: #545c64;
                        /*选中列*/
                        .el-menu-item {
                            background-color: #545c64;
                        }
                        .el-submenu__title {
                            i {
                                color: #fff;
                            }
                        }
                    }
                    .el-menu:first-child {
                        overflow-y: auto !important;
                    }
                    .el-menu-collapsed li:hover {
                        background-color: #434a50;
                    }
                    /*当前选中菜单*/
                    .is-opened {
                        color: #fff;
                        background-color: #fff;
                    }
                    .collapsed {
                        width: 60px;
                        .item {
                            position: relative;
                        }
                        .submenu {
                            position: absolute;
                            top: 0;
                            left: 60px;
                            z-index: 99999;
                            height: auto;
                            display: none;
                        }
                    }
                }
                .menu-collapsed {
                    flex: 0 0 60px;
                    width: 60px;
                }
                .menu-expanded {
                    flex: 0 0 230px;
                    width: 230px;
                }
                .content-container {
                    flex: 1;
                    overflow-y: scroll;
                    padding: 20px;
                    background-color: #d3d7d4;
                    .breadcrumb-container {
                        display: none;
                        .title {
                            width: 200px;
                            float: left;
                            color: #475669;
                        }
                        .breadcrumb-inner {
                            float: right;
                        }
                    }
                    .content-wrapper {
                        box-sizing: border-box;
                    }
                }
            }
        }
    </style>
    

    components/Dashboard.vue

    <template>
        <div>
            <p>首页</p>
        </div>
    </template>
    <script>
    </script>
    <style>
    </style>
    

    components/system/Contract.vue

    <template>
        <div>
            <p>联系人</p>
        </div>
    </template>
    <script>
    </script>
    <style>
    </style>
    

    下篇文章:https://www.jianshu.com/p/f062c9ff7b48

    相关文章

      网友评论

          本文标题:(二)vue + element UI 搭建后台管理导航菜单

          本文链接:https://www.haomeiwen.com/subject/rgjczxtx.html