写在后面
每次反复写路由的时候是不是会感觉很烦,特地是我的项目大的时候,路由会有特地多,看都看不过去,所以这里我是有了一个 router.json 的配置文件来对路由做一些简略的配置,而后让路由和左侧菜单栏能够同时主动生成。
router.json
次要配置项如下:
{
"name": "routerConfig",
"menu": [{
"id": "1", // 路由 id,不能反复
"name": "home",// 路由名字
"path": "/homePage",// 路由门路
"label": "首页",// 菜单题目
"selected": true,// 默认选中
"icon": "el-icon-monitor",// 菜单显示图标
"open": true,// 默认关上
"component": "homePage/homePage.vue",// 组件路由
"children": [ // 子菜单
{
"id": "3",
"name": "getCover",
"path": "/getCover",
"label": "封面截取",
"selected": false,
"icon": "el-icon-scissors",
"open": false,
"component": "getCover/getCover.vue",
"children": []}
]
},{
"id": "2",
"name": "testPage",
"path": "/testPage",
"label": "测试",
"selected": false,
"icon": "el-icon-setting",
"open": false,
"component": "test/test.vue",
"children": []},{
"id": "5",
"name": "testMenu",
"path": "/testMenu",
"label": "菜单测试",
"selected": false,
"icon": "el-icon-setting",
"open": false,
"component": "testMenu/testMenu.vue",
"children": []}]
}
配置次要分为两局部,一部分因为菜单生成,一部分用于路由生成,当然两者也有共用的局部
路由生成
import Vue from 'vue'
import VueRouter from 'vue-router'
import ro from "element-ui/src/locale/lang/ro";
Vue.use(VueRouter)
// 引入配置文件 router.json
let routerMenu = require('@/config/router.json');
routerMenu = routerMenu.menu;
let menu = [];
// 配置路由
let formatRoute = function (routerMenu,menu){for(let i = 0; i < routerMenu.length; i++){
let temp = {path: routerMenu[i].path,
name: routerMenu[i].name,
// 这块要留神
// 用 require 这种形式引入的时候,会将你的 component 别离打包成不同
// 的 js,加载的时候也是按需加载,只用拜访这个路由网址时才会加载
// 这个 js
component: resolve => require([`@/views/${routerMenu[i].component}`], resolve)
};
menu.push(temp);
if(routerMenu[i].children && routerMenu[i].children.length > 0){
// 递归生成子菜单的路由
formatRoute(routerMenu[i].children,menu);
}
}
}
// 初始化
formatRoute(routerMenu,menu);
// 重定向设置
const routes = [
{
path: '/',
redirect: '/homePage'
},
]
// 将生成的路由文件 push 进去
for(let i = 0; i < menu.length; i++)
routes.push(menu[i]);
const router = new VueRouter({routes})
export default router
菜单生成
<template>
<div id="leftMenu">
</div>
</template>
<script>
export default {
name: "left",
data(){
return{menu:[]
}
},
methods:{
// 通过路由 id 来找节点
findNodeById(node,id){for(let i = 0; i < node.length; i++){if(id == node[i].id){node[i].selected = true;
if(node[i].children && node[i].children.length > 0){this.findNodeById(node[i].children,id);
}
node[i].open = !node[i].open;
if(this.$route.path !== node[i].path) this.$router.push(node[i].path);
}else{node[i].selected = false;
if(node[i].children && node[i].children.length > 0){this.findNodeById(node[i].children,id);
}else{}}
}
},
// 选中菜单节点
chooseNode(id){this.findNodeById(this.menu,id);
let domTree = this.generatorMenu(this.menu,'',0)
let leftMenu = document.getElementById('leftMenu');
leftMenu.innerHTML = domTree;
},
// 动静生成菜单目录
generatorMenu(menu,temp,floor){for(let i = 0; i < menu.length; i++){
temp += `<div style="width: max-content">
<div class="menuOption" onclick="chooseNode(${menu[i].id})"
style="text-indent: ${floor}em;
background-color: ${menu[i].selected?'aquamarine':''};
cursor: pointer;
margin-top: 0.3rem;">
<i class="${menu[i].icon}"></i>
${menu[i].label}`
if(!menu[i].open && menu[i].children && menu[i].children.length > 0){temp += `<i style="margin-left: 1rem" class="el-icon-arrow-down"></i>`}else{if(menu[i].open && menu[i].children && menu[i].children.length > 0){temp += `<i style="margin-left: 1rem" class="el-icon-arrow-up"></i>`}
}
temp += `</div>`
if(menu[i].open && menu[i].children && menu[i].children.length != 0){temp = this.generatorMenu(menu[i].children,temp,floor+1);
}
temp += `</div>`
}
return temp;
}
},
created() {},
mounted() {
window.chooseNode = this.chooseNode;
let menu = [];
// 获取路由菜单配置文件
const router = require('@/config/router.json');
menu = router.menu;
this.menu = menu;
let domTree = this.generatorMenu(menu,'',0)
let leftMenu = document.getElementById('leftMenu');
leftMenu.innerHTML = domTree;
}
}
</script>
<style scoped>
#leftMenu{min-height: calc(100vh - 44px - 1rem);
background-color: cornflowerblue;
text-align: left;
padding: 0.5rem 1rem;
font-size: large;
font-weight: bold;
}
.selectedM{background-color: aquamarine;}
.menuOption{cursor: pointer;}
</style>
成果
左侧菜单便是主动生成的,点击菜单栏也会跳转到对应的路由地址,当然,款式有点丑,但款式的话能够本人后续再调整。
这样的话,咱们新加菜单的时候只须要在配置文件中配置好,就能够间接写编写页面,这样也给咱们省下了很多工夫。