ElementUI 复杂顶部和左侧导航栏实现

描述:如图

代码实现:

首先在store.js中添加两个状态:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
    topNavState: 'home',
    leftNavState: 'enterprise'
}
export default new Vuex.Store({
    state
})

App.vue内容:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>
<script>
  export default {
    name: 'app'
  }
</script>

main.js代码:

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import store from './store.js'
import 'element-ui/lib/theme-chalk/index.css'
import '@/assets/iconfont.css'
import '@/assets/css/style.css'
Vue.config.productionTip = false
Vue.use(ElementUI)

new Vue({
    router,
    store,
    el: '#app',
    render: h => h(App)
})

router/index.js文件声明路由:

其中:行程计划、任务、通讯录属于首页大板块(topNavState=“home”);企业信息、车辆信息、部门信息都属于enterprise这一大板块(topNavState=“enterprise”)

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/home.vue'
import Dashboard from '@/components/workbench/dashboard.vue'
import Mission from '@/components/workbench/mission.vue'
import Plan from '@/components/workbench/plan.vue'
import MailList from '@/components/workbench/maillist.vue'
import LeftNav from '@/components/navs/leftNav.vue'
import EnterpriseList from '@/components/enterprise/index.vue'
import EnterpriseAdd from '@/components/enterprise/add.vue'
import EnterpriseDetail from '@/components/enterprise/detail.vue'
import EnterpriseValidate from '@/components/enterprise/validate.vue'
import VehicleManage from '@/components/vehicle/index.vue'
import VehicleAdd from '@/components/vehicle/add.vue'
import DeptManager from '@/components/dept/index.vue'
import NotFound from '@/components/404.vue'
import Register from '@/components/admin/register.vue'

// 懒加载方式,当路由被访问的时候才加载对应组件
const Login = resolve => require(['@/components/login'], resolve)

Vue.use(Router)

let router = new Router({
  routes: [
    {
      path: '/login',
      type: 'login',
      component: Login
    },
    {
      path: '/register',
      type: 'register',
      component: Register
    },
    {
      path: '*',
      component: NotFound
    },
    {
      path: '/',
      type: 'home',
      name: 'home',
      redirect: '/dashboard',
      component: Home,
      menuShow: true,
      children: [
        {
          path: '/dashboard',
          component: Dashboard,
          name: 'dashboard',
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-home', // 图标样式class
          menuShow: true,
          children: [
            { path: '/dashboard', component: Dashboard, name: '首页', menuShow: true }
          ]
        },
        {
          path: '/mySet',
          component: HomeNav,
          name: '我的设置',
          iconCls: 'el-icon-menu',
          menuShow: true,
          children: [
            { path: '/mySet/plan', component: Plan, name: '行程计划', menuShow: true },
            { path: '/mySet/mission', component: Mission, name: '我的任务', menuShow: true },
            { path: '/mySet/maillist', component: MailList, name: '通讯录', menuShow: true }
          ]
        }
      ]
    },
    {
      path: '/enterpriseManager',
      type: 'enterprise', // 顶部导航类型
      name: 'enterprise', // 左侧导航对应所属
      component: Home,
      redirect: '/enterprise/list',
      menuShow: true,
      children: [
        {
          path: '/enterpriseList',
          component: LeftNav,
          name: 'enterpriseList',
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-home', // 图标样式class
          menuShow: true,
          children: [
            { path: '/enterprise/list', component: EnterpriseList, name: '企业列表', menuShow: true },
            { path: '/enterprise/detail', component: EnterpriseDetail, name: '企业详情', menuShow: false }
          ]
        },
        {
          path: '/enterpriseAdd',
          component: LeftNav,
          name: 'enterpriseAdd',
          leaf: true, // 只有一个节点
          iconCls: 'el-icon-menu',
          menuShow: true,
          children: [
            { path: '/enterprise/add', component: EnterpriseAdd, name: '企业添加', menuShow: true }
          ]
        },
        {
          path: '/enterpriseValidate',
          component: LeftNav,
          name: 'enterpriseValidate',
          leaf: true, // 只有一个节点
          iconCls: 'el-icon-menu',
          menuShow: true,
          children: [
            { path: '/enterprise/validate', component: EnterpriseValidate, name: '企业认证', menuShow: true }
          ]
        }
      ]
    },
    {
      path: '/vehicleManager',
      type: 'enterprise',
      name: 'vehicle',
      component: Home,
      redirect: '/vehicle/list',
      menuShow: true,
      children: [
        {
          path: '/vehicleList',
          component: LeftNav,
          name: 'vehicleList',
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-home', // 图标样式class
          menuShow: true,
          children: [
            { path: '/vehicle/list', component: VehicleManage, name: '车辆信息', menuShow: true }
          ]
        },
        {
          path: '/vehicleAdd',
          component: LeftNav,
          name: 'vehicleAdd',
          leaf: true, // 只有一个节点
          iconCls: 'el-icon-menu',
          menuShow: true,
          children: [
            { path: '/vehicle/add', component: VehicleAdd, name: '车辆添加', menuShow: true }
          ]
        }
      ]
    },
    {
      path: '/deptManager',
      type: 'enterprise',
      name: 'dept',
      component: Home,
      redirect: '/dept/list',
      menuShow: true,
      children: [
        {
          path: '/deptList',
          component: LeftNav,
          name: 'deptList',
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-home', // 图标样式class
          menuShow: true,
          children: [
            { path: '/dept/list', component: DeptManager, name: '部门信息', menuShow: true }
          ]
        }
      ]
    }

  ]
});

export default router

leftNav.vue文件中主要是左侧导航菜单加载代码:

<template>
  <el-col :span="24" class="main">
    <!--左侧导航-->
    <aside :class="{showSidebar:!collapsed}">
      <!--展开折叠开关-->
      <div class="menu-toggle" @click.prevent="collapse">
        <i class="iconfont icon-outdent" v-show="!collapsed" title="收起"></i>
        <i class="iconfont icon-indent" v-show="collapsed" title="展开"></i>
      </div>
      <!--导航菜单-->
      <el-menu router :collapse="collapsed">
        <template v-for="(issue,index) in $router.options.routes">
          <template v-if="issue.name === $store.state.leftNavState"> <!-- 注意:这里就是leftNavState状态作用之处,当该值与router的根路由的name相等时加载相应菜单组 -->
            <template v-for="(item,index) in issue.children">
              <el-submenu v-if="!item.leaf" :index="index+''" v-show="item.menuShow">
                <template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template>
                <el-menu-item v-for="term in item.children" :key="term.path" :index="term.path" v-if="term.menuShow"
                              :class="$route.path==term.path?'is-active':''">
                  <i :class="term.iconCls"></i><span slot="title">{{term.name}}</span>
                </el-menu-item>
              </el-submenu>
              <el-menu-item v-else-if="item.leaf&&item.children&&item.children.length" :index="item.children[0].path"
                            :class="$route.path==item.children[0].path?'is-active':''" v-show="item.menuShow">
                <i :class="item.iconCls"></i><span slot="title">{{item.children[0].name}}</span>
              </el-menu-item>
            </template>
          </template>
        </template>
      </el-menu>
    </aside>
    <!--右侧内容区-->
    <section class="content-container">
      <div class="grid-content bg-purple-light">
        <el-col :span="24" class="content-wrapper">
          <transition name="fade" mode="out-in">
            <router-view></router-view>
          </transition>
        </el-col>
      </div>
    </section>
  </el-col>
</template>
<script>
  export default {
    name: 'leftNav',
    data () {
      return {
        collapsed: false
      }
    },
    methods: {
      //折叠导航栏
      collapse: function () {
        this.collapsed = !this.collapsed;
      }
    }
    }
  }
</script>

home.vue是后台主页组件代码

<template>
  <el-row class="container">
    <!--头部-->
    <el-col :span="24" class="topbar-wrap">
      <div class="topbar-logo topbar-btn">
        <a href="/"><img src="../assets/logo.png" style="padding-left:8px;"></a>
      </div>
      <div class="topbar-logos" v-show="!collapsed">
        <a href="/" style="color: #fff;">车车综合管理平台</a>
      </div>
      <div class="topbar-title">
        <el-row v-show="$store.state.topNavState==='home'"> <!-- 注意:这里就是topNavState状态作用之处,根据不同值显示相应头部菜单组 -->
          <el-col :span="24">
            <el-menu :default-active="defaultActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :router="true">
              <el-menu-item index="/">工作台</el-menu-item>
              <el-menu-item index="/enterpriseManager">企业管理</el-menu-item>
              <el-menu-item index="/orderManager">订单管理</el-menu-item>
              <el-menu-item index="/systemManager">系统管理</el-menu-item>
            </el-menu>
          </el-col>
        </el-row>
        <el-row v-show="$store.state.topNavState==='enterprise'">
          <el-col :span="24">
            <el-menu :default-active="defaultActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :router="true">
              <el-menu-item index="/enterpriseManager">企业信息</el-menu-item>
              <el-menu-item index="/vehicleManager">车辆信息</el-menu-item>
              <el-menu-item index="/deptManager">组织架构</el-menu-item>
            </el-menu>
          </el-col>
        </el-row>
      </div>
      <div class="topbar-account topbar-btn">
        <div class="topbar-timer">
          <span><i class="login-name">{{nickname}},</i></span>
        </div>
        <el-dropdown trigger="click">
          <span class="el-dropdown-link userinfo-inner">
            <img src="../assets/photo/default-user.png" width="30" height="30" alt="头像">
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>
              <div @click="jumpTo('/user/profile')"><span style="color: #555;font-size: 14px;">个人信息</span></div>
            </el-dropdown-item>
            <el-dropdown-item>
              <div @click="jumpTo('/user/changepwd')"><span style="color: #555;font-size: 14px;">修改密码</span></div>
            </el-dropdown-item>
            <el-dropdown-item divided @click.native="logout">退出登录</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </el-col>

    <!--中间-->
    <transition name="fade" mode="out-in">
      <router-view></router-view>
    </transition>
  </el-row>
</template>
<script>
  import $ from 'jquery'

  export default {
    name: 'home',
    data () {
      return {
        defaultActiveIndex: "/",
        loading: false,
        nickname: '',
        collapsed: false
      }
    },
    created() {
      // 组件创建完后获取数据,
      // 此时 data 已经被 observed 了
      this.fetchNavData();
    },
    methods: {
      handleSelect(index){
        this.defaultActiveIndex = index;
      },
      //折叠导航栏
      collapse () {
        this.collapsed = !this.collapsed;
      },
      fetchNavData () { // 初始化菜单激活项
        var cur_path = this.$route.path; //获取当前路由
        var routers = this.$router.options.routes; // 获取路由对象
        var nav_type = "home", nav_name = "enterprise";
        for (var i = 0; i < routers.length; i++) {
          var children = routers[i].children;
          if(children){
            for (var j = 0; j < children.length; j++) {
              var grand_children = children[j].children;
              if(grand_children){
                for (var k = 0; k < grand_children.length; k++) {
                  if (grand_children[k].path === cur_path) {
                    nav_type = routers[i].type;
                    nav_name = routers[i].name;
                    break;
                  }
                }
              }
            }
          }
        }
        this.$store.state.topNavState = nav_type; //改变topNavState状态的值
        this.$store.state.leftNavState = nav_name; //改变leftNavState状态的值
        if(nav_type == "home"){
          this.defaultActiveIndex = "/";
        } else {
          this.defaultActiveIndex = "/" + nav_name + "Manager";
        }
      },
      jumpTo(url){
        this.defaultActiveIndex = url;
        this.$router.push(url); //用go刷新
      },
    },
    watch: {
      '$route': 'fetchNavData' //监听router改变时,渲染菜单激活项
    }
  }
</script>

猜你喜欢

转载自www.cnblogs.com/yeqrblog/p/8991587.html
今日推荐