多级路由

`后端接口`
```json
{
"code": 0,
"data": [
{
"alias": "用户管理",
"children": [
{
"alias": "用户信息",
"component": "Info",
"hasChildren": false,
"icon": "info",
"id": 1,
"name": "Info",
"path": "info"
},
{
"alias": "个人中心",
"component": "Profile",
"hasChildren": false,
"icon": "info",
"id": 2,
"name": "Profile",
"path": "profile"
}
],
"component": "User",
"hasChildren": true,
"icon": "user",
"id": 0,
"name": "User",
"path": "/user"
},
{
"alias": "订单管理",
"component": "Order",
"hasChildren": false,
"icon": "ordered-list",
"id": 3,
"name": "Order",
"path": "/order"
}
],
"msg": "ok"
}
```
`home.vue`
```html
<template>
<a-layout id="components-layout-demo-side" style="min-height: 100vh">
<a-layout-sider v-model="collapsed" collapsible>
<div class="logo" />
<a-menu theme="dark" :default-selected-keys="['1']" mode="inline">
<!-- 解析菜单 -->
<template v-for="menu in menus">
<template v-if="menu.hasChildren">
<a-sub-menu :key="menu.id">
<span slot="title"><a-icon :type="menu.icon" /><span>{{menu.alias}}</span></span>
<a-menu-item v-for="child in menu.children" :key="child.id" @click="$router.push({name: child.name})">
<a-icon :type="child.icon" />
<span>{{child.alias}}</span>
</a-menu-item>
</a-sub-menu>
</template>
<template v-else>
<a-menu-item :key="menu.id" @click="$router.push({name: menu.name})">
<a-icon :type="menu.icon" />
<span>{{menu.alias}}</span>
</a-menu-item>
</template>
</template>
</a-menu>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0" />
<a-layout-content style="margin: 0 16px">
<a-breadcrumb style="margin: 16px 0">
<a-breadcrumb-item>User</a-breadcrumb-item>
<a-breadcrumb-item>Bill</a-breadcrumb-item>
</a-breadcrumb>
<div :style="{ padding: '24px', background: '#fff', minHeight: '360px' }">
<router-view name="content"></router-view>
</div>
</a-layout-content>
<a-layout-footer style="text-align: center">
Ant Design ©2018 Created by Ant UED
</a-layout-footer>
</a-layout>
</a-layout>
</template>
<script>
import axios from "axios"
export default {
data() {
return {
collapsed: false,
menus: []
};
},
mounted() {
this.getMenus();
},
methods: {
getMenus() {
axios.get("http://127.0.0.1:8199/menus").then(ret=>{
this.menus = ret.data.data;
})
}
}
};
</script>
<style>
#components-layout-demo-side .logo {
height: 32px;
background: rgba(255, 255, 255, 0.2);
margin: 16px;
}
</style>
```
`router/index.js`
```javascript
import axios from 'axios'
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
// 从后端获取路由, 通过router.addRoute动态添加路由
axios.get('http://127.0.0.1:8199/menus').then(ret=>{
ret.data.data.forEach(item=>{
router.addRoute('Home', {
path: item.path,
name: item.name,
components: {
content: () => import('../views/'+item.component)
}
})
if (item.hasChildren) {
item.children.forEach(child=>{
console.log('child:', child, item.name)
router.addRoute(item.name, {
path: child.path,
name: child.name,
components: {
user: () => import('../views/'+child.component)
}
})
})
}
})
})
// 去除跳转当前路由出错消息
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
export default router
```
`User.vue`
```html
<template>
<div>
<router-view name="user"></router-view>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
```
`Profile.vue`
```html
<template>
<div>
<h1>Profile</h1>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
```
`Order.vue`
```html
<template>
<div>
<h1>Order page</h1>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
```
`Info.vue`
```html
<template>
<div>
<h1>Info Page</h1>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
```