vue 后台管理系统(1)路由配置

vue

vue-router 结构一致的配置

import Vue from 'vue';

import Router from 'vue-router';

import Layout from './index.vue';

Vue.use(Router);

/**

* 这种配置方式有以下弊端

* 1. product 命名空间重复写多次 代码臃肿

* 2. 导航的链式关系需要额外的代码逻辑指定(preNav), 比如 商品管理 > 商品列表 > 商品详情 > 商品编辑

* 您可能会想到路由链式关系可以通过路由段来匹配:/goods/product/:id/edit 一个路由段对应一个路由

* => (1) /goods (2) /goods/product (3) /goods/product/:id (4) /goods/product/:id/edit

* 这样做比较麻烦,而且也没有相关API支持

* 3. 从 $route.matched 获取当前匹配的路径是行不通的,比如访问 /goods/product/1/edit 只匹配到了两个

(1) /goods

(2) /goods/product/1/edit

*

*/

export const routes = [

{

name: 'M1',

component: Layout,

path: '/goods',

redirect: '/goods/product',

meta: {

title: '商品管理'

},

children: [

{

name: 'M2',

component: () => import('../Product.vue'),

path: 'product',

meta: {

title: '商品列表',

activeMenu: 'M2'

}

},

{

name: 'M3',

component: () => import('../Product.vue'),

path: 'product/add',

meta: {

title: '增加商品',

activeMenu: 'M2'

}

},

{

name: 'M4',

component: () => import('../Product.vue'),

path: 'product/:id',

meta: {

title: '商品详情',

activeMenu: 'M2'

}

},

{

name: 'M5',

component: () => import('../Product.vue'),

path: 'product/:id/edit',

meta: {

title: '编辑商品',

activeMenu: 'M2',

preNav: 'M4'

}

}

]

}

];

export default new Router({

routes: routes

});

自动注入

页面文件目录按照某种规格编写,读取文件目录生成路由,与 nuxt 类似,约束性太强,而且目录看起来总觉得很奇怪,故不采用。

自定义结构

路由结构层次清晰,能满足菜单/导航/权限 等配置。

import Vue from 'vue';

import Router from 'vue-router';

import Layout from './index.vue';

Vue.use(Router);

/**

* routes 包含了导航链式关系 以及 菜单关系

*/

export const routes = [

{

name: 'M1',

component: Layout,

path: '/product',

redirect: '/product/index',

meta: {

title: '商品管理'

},

children: [

{

name: 'M2',

component: () => import('../Product.vue'),

path: 'index',

meta: {

title: '商品列表'

}

},

{

name: 'M3',

component: () => import('../Brand.vue'),

path: 'brand',

meta: {

title: '品牌管理'

}

},

{

name: 'M4',

component: () => import('../Category.vue'),

path: 'category',

meta: {

title: '类目管理'

}

}

]

},

{

name: 'M5',

component: Layout,

path: '/order',

redirect: '/order/index',

meta: {

title: '订单管理'

},

children: [

{

name: 'M6',

component: () => import('../OrderList.vue'),

path: 'index',

meta: {

title: '订单列表'

},

children: [

{

name: 'M7',

component: () => import('../OrderDetail.vue'),

path: 'add',

hidden: true,

meta: {

title: '创建订单'

}

},

{

name: 'M8',

component: () => import('../OrderDetail.vue'),

path: ':orderId',

hidden: true,

meta: {

title: '订单详情'

},

children: [

{

name: 'M9',

component: () => import('../OrderDetail.vue'),

path: 'edit',

meta: {

title: '编辑订单'

}

}

]

}

]

}

]

}

];

/**

* 生成 vue-router routes

*/

const makeRoutes = () => {

const rList = [];

const rawChildren = (parent, children = [], top) => {

children.forEach(item => {

item.path = (parent.path + '/' + item.path).replace('//', '/');

const child = {

...item

};

delete child.children;

top.children.push(child);

rawChildren(item, item.children, top);

});

};

routes.forEach(item => {

const child = {

...item,

children: []

};

rawChildren(child, item.children || [], child);

rList.push(child);

});

return rList;

};

export default new Router({

routes: makeRoutes()

});

左侧菜单配置:

<template>

<el-menu

class="menu"

:default-active="activeMenu"

background-color="#282c43"

text-color="#fff"

active-text-color="#fc652f"

>

<MenuItem v-for="item in routes" :menu="item" :key="item.name" :routes="routes" />

</el-menu>

</template>

<script>

// sidebar.vue

import { routes } from '../router';

import MenuItem from './menu-item';

export default {

components: {

MenuItem

},

data() {

return {

routes,

isCollapse: true

};

},

computed: {

activeMenu() {

const meta = this.$route.meta;

return meta && meta.menuValue ? meta.menuValue : this.$route.name;

}

}

};

</script>

<style scoped>

.menu {

border-right: 0;

}

.menu-item {

padding: 0 12px;

line-height: 40px;

}

</style>

<template>

<div v-if="menu.meta && !menu.hidden">

<template v-if="!hasChildren(menu)" >

<el-menu-item>

<template slot="title">

<span slot="title">{{ menu.meta.title }}</span>

</template>

</el-menu-item>

</template>

<template v-else>

<el-submenu :index="getMenuIndex(menu)">

<template slot="title">

<i class="el-icon-user-solid" v-if="showIcon"></i>

<span slot="title">{{ menu.meta.title }}</span>

</template>

<child-menu

v-for="child in menu.children"

:key="child.name"

:menu="child"

:show-icon="false"

/>

</el-submenu>

</template>

</div>

</template>

<script>

// menu-item.vue

import router from '../router';

export default {

name: 'child-menu',

props: {

menu: {

type: Object,

default: null

},

'show-icon': {

type: Boolean,

default: true

}

},

created() {

this.$watch('menu', v => {

console.log(v);

});

},

methods: {

getMenuIndex($route) {

return $route.name;

},

hasChildren(menu) {

if (!menu.children) return false;

return !!menu.children.filter(menu => !menu.hidden).length;

},

gotoPath(route) {

if (route.name !== this.$route.name) {

this.$router.push({ name: route.name });

}

},

hasPermission(route) {

return true;

}

}

};

</script>

<style scoped>

.menu {

border-right: 0;

}

.menu-item {

padding: 0 12px;

line-height: 40px;

}

</style>

导航面包屑:

<template>

<div>

<span v-for="bread in breadList" :key="bread.name">

{{ bread.meta.title }}

</span>

</div>

</template>

<script>

import { routes } from './router';

export default {

data() {

return {

routes,

breadList: []

};

},

created() {

let res = null;

const find = (list, path) => {

list.forEach(item => {

const curPath = [...path].concat(item);

if (item.name === this.$route.name) {

res = curPath;

}

item.children && find(item.children, curPath);

});

};

find(routes, []);

this.breadList = res;

}

};

</script>

以上是 vue 后台管理系统(1)路由配置 的全部内容, 来源链接: utcz.com/z/380162.html

回到顶部