描述:如图

项目路径如下图所示:

代码实现:
首先在store.js中添加两个状态:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
topNavState: 'home',
leftNavState: 'home'
}
export default new Vuex.Store({
state
})
App.vue内容:
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 LeftNav from '@/components/nav/leftNav.vue'
import Home from '@/views/home.vue'
import Dashboard from '@/views/workbench/dashboard.vue'
import Mission from '@/views/workbench/mission/mission.vue'
import Plan from '@/views/workbench/plan.vue'
import Maillist from '@/views/workbench/maillist.vue'
import EnterpriseList from '@/views/enterprise/index.vue'
import EnterpriseAdd from '@/views/enterprise/add.vue'
import EnterpriseDetail from '@/views/enterprise/detail.vue'
import EnterpriseValidate from '@/views/enterprise/validate.vue'
import VehicleManage from '@/views/vehicle/index.vue'
import DeptManager from '@/views/dept/index.vue'
import NotFound from '@/components/404.vue'
// 懒加载方式,当路由被访问的时候才加载对应组件
const Login = resolve => require(['@/views/login'], resolve)
Vue.use(Router)
let router = new Router({
routes: [
{
path: '/login',
type: 'login',
component: Login
},
{
path: '*',
component: NotFound
},
{
path: '/',
type: 'home', // 根据type区分不同模块(顶部导航)
name: 'home', // 根据name区分不同子模块(左侧导航)
redirect: '/dashboard',
component: Home,
menuShow: true,
children: [
{
path: '/dashboard',
component: LeftNav,
name: 'dashboard', // 当前路由的name
leaf: true, // 只有一个节点
iconCls: 'iconfont icon-home', // 图标样式class
menuShow: true,
children: [
{ path: '/dashboard', component: Dashboard, name: '首页', menuShow: true }
]
},
{
path: '/mySet',
component: LeftNav,
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: '/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 }
]
}
]
}
]
});
router.beforeEach((to, from, next) => {
// console.log('to:' + to.path)
if (to.path.startsWith('/login')) {
window.localStorage.removeItem('access-user')
next()
} else if(to.path.startsWith('/register')){
window.localStorage.removeItem('access-user')
next()
} else {
let user = JSON.parse(window.localStorage.getItem('access-user'))
if (!user) {
next({path: '/login'})
} else {
next()
}
}
});
export default router
特别说明:
这里的路由对象router ,设置的是最多三级,一级路由主要对应的是顶部导航和其他无子页面的路由,二级和三级路由分别对应的是左侧导航的一级和二级菜单(比如三级路由对应的就是左侧导航的二级菜单),二级路由设置leaf属性,值为true表明该路由下没有子菜单(如果该路由下的某页面不显示在左侧导航,不算子菜单)。
leftNav.vue文件中主要是左侧导航菜单加载代码:
{{item.name}}
{{term.name}}
{{item.children[0].name}}
home.vue是后台主页组件代码
车车综合管理
{{nickname}}
个人信息
修改密码
退出登录
注意fetchNavData()这个方法,主要是根据当前跳转的路由,去找到这个路由对应的type(对应顶部导航栏的分类)和name(对应左侧导航栏的分类),然后保存type和name到$store中,这样在顶部导航可以根据$store中的type显示相应的菜单,同样在左侧导航就可以取到这个name值并显示相应的左侧菜单栏了。
之前写的左侧导航栏(leftNav.vue)的代码有个不足的地方——当前打开页面是三级路由(也就是左侧导航的二级菜单)时,刷新当前页,(在左侧导航中)当前路由所属的一级菜单没有默认打开。
解决方案已修改,在leftNav.vue中添加defaultLeftNavOpened()方法,详情可以回看leftNav.vue的代码。
对于这个项目的demo,也放到了github共享,请看github地址:https://github.com/yqrong/ccproject.git
最近这段时间把项目修改了下(将顶部导航也提取出来作为命名视图),详情请看下篇:
ElementUI+命名视图实现复杂顶部和左侧导航栏
补充:
今天有位细心的网友发现了一个小问题:
左侧导航当前激活的是非第一个菜单时,切换其他顶部导航再切换回来,会有两个激活的菜单。
解决:el-menu标签缺少default-active属性设置,加上即可。
写代码还是不够细心,自我检讨一下。