作为后端的CV工程师,此篇文章第一次写关于vue的文章,术业有专攻,倘若有前端开发者发现此篇文章有哪里不当之处,望君指出,不胜感激!
首先静态路由部分
import Vue from 'vue'
import Router from 'vue-router'
import Layout from '../layout'
Vue.use(Router)
var constantRouterMap=[
{path: '/', name: 'Login',hidden:true, component: resolve => require(['@/views/Login'], resolve)},
{
path: '/index',
name: 'Layout',
component: Layout,
redirect:'/home',
children: [{
path: '/home',
name: 'Home',
component: () => import('../views/Home'),
meta: {
title: '首页',
icon: 'vue-dsn-icon-zhuye',
fixed: true
}
}]
},
{
path: '/chat',
name: '聊天公告',
component: Layout,
hidden:true,
redirect:'/chatmassage',
children: [{
path: '/chatmassage',
name: 'chatmassage',
component: () => import('../views/Chats/Chat'),
meta: {
title: '聊天公告'
}
}],
}
];
export default new Router({
model:'hash',
routes: constantRouterMap
})
处理动态路由部分
const _import = require('../router/_import_' + process.env.NODE_ENV) //获取组件的方法
import { GetMenuList} from "@/utils/api";
import Layout from '../layout'
let getRouter //用来获取后台拿到的路由
export const initMenu = (router, store)=> {
if(!getRouter) {
if (store.state.routes.length > 0) {
return;
}
GetMenuList().then(resp => {
if (resp && resp.status == 200) {
getRouter=resp.data.menus;
getRouter = filterAsyncRouter(getRouter) //过滤路由
router.addRoutes(getRouter) //动态添加路由
store.commit('initMenu', getRouter);
}
}).finally(() => {
})
}
}
function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === "Layout") { //Layout组件特殊处理
route.component = Layout
} else {
route.component = _import(route.component)
}
}
if (route.children && route.children.length>0) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
_import_production.js如下:
module.exports = file => () => import('@/views/' + file + '.vue')
然后在路由守卫中初始化左侧菜单
router.beforeEach((to, from, next) => {
let Token = localStorage.getItem("authorization")
if(to.path === '/'){
return next()
}
if (!Token && to.path !== '/') {
return next('/')
}else {
initMenu(router, store);
if(to.path=='/chat')
store.commit("updateMsgList", []);
next();
}
});
后台返回数据如下:
[{ "name": "组织管理", "path": "/organization", "children": [{ "name": "菜单权限管理", "path": "/menus", "component": "Users/User", "meta": { "icon": "", "title": "菜单权限管理" } }, { "name": "用户管理", "path": "/user", "component": "Users/User", "meta": { "icon": "", "title": "用户管理" } }, { "name": "角色管理", "path": "/index/roles", "component": "Users/User", "meta": { "icon": "", "title": "角色管理" } }],
"component": "Layout",
"meta": {
"icon": "vue-dsn-icon-drxx10",
"title": "组织管理"
}
}, {
"name": "系统管理",
"path": "/system",
"children": [{
"name": "日志管理",
"path": "/logs",
"component": "System/Logs/OperatingLog/Index",
"meta": {
"icon": "",
"title": "日志管理"
}
}, {
"name": "接口管理",
"path": "/swagger",
"component": "System/Swagger/Index",
"meta": {
"icon": "",
"title": "接口管理"
}
}, {
"name": "SQL监控",
"path": "/druid",
"component": "System/Druid/Index",
"meta": {
"icon": "",
"title": "SQL监控"
}
}],
"component": "Layout",
"meta": {
"icon": "vue-dsn-icon-GitHub",
"title": "系统管理"
}
}, {
"name": "文件系统",
"path": "/files",
"children": [{
"name": "我的文件",
"path": "/index/files",
"component": "Users/User",
"meta": {
"icon": "",
"title": "我的文件"
}
}, {
"name": "轮播图管理",
"path": "/index/rotations",
"component": "Users/User",
"meta": {
"icon": "",
"title": "轮播图管理"
}
}],
"component": "Layout",
"meta": {
"icon": "vue-dsn-icon-zhbg-file",
"title": "文件系统"
}
}]
Layout部分参照花裤衩大神的布局
<template>
<div class="side-menu-wrapper">
<el-scrollbar wrap-class="scrollbar">
<el-menu
:default-active="activeMenu"
:collapse="collapsed"
:unique-opened="true"
background-color="#263238"
text-color="#fff"
active-text-color="#409eff"
>
<SideMenuItem
v-for="route in routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import SideMenuItem from './SideMenuItem'
export default {
name: 'SideMenu',
components: { SideMenuItem },
computed: {
...mapGetters('app', ['collapsed']),
routes() {
return this.$router.options.routes.concat(this.$store.state.routes)
},
activeMenu() {
const route = this.$route
const { meta, path } = route
if (meta.activeMenu) {
return meta.activeMenu
}
return path
}
},
}
</script>
<style lang="less">
@import "../../../assets/less/side-menu";
</style>
效果如下: