前言
本文启发自实际项目中,随着项目不断增长,页面越来越多,不得不把vue-router的路由管理化繁为简、逐渐自动化的一个过程,希望能引发大家的思考;
顺理成章的路由管理方式
在一个Vue + Vue-Router的单页应用中,我们一般会在一个js文件中统一管理我们的页面,具体如下:
const routes = [{
path: '/page-one/index',
component: () => import('./pages/page-one/index'),
meta: {
title: 'page-one-index'
}
}, {
path: '/page-one/sub-page',
component: () => import('./pages/page-one/sub-page'),
meta: {
title: 'page-one-sub-page'
}
}, {
path: '/page-two/index',
component: () => import('./pages/page-two/index'),
meta: {
title: 'page-two-index'
}
}, {
// 其他页面...
}];
export default new VueRouter({ routes });
这种方式的优点就是能集中化的管理页面;而缺点也是明显的,随着项目规模越来越大,单个js会管理大量的页面路由,维护起来有一定的困难。
拆分与聚合
既然大量的页面路由在单个js文件维护存在困难,那不如就路由根据业务进行拆分管理,每个业务对应的页面由其对应的路由文件
来管理,然后在总的路由文件中再聚合各业务的路由文件
。
// page-one-router.js
// page-one管理的路由文件
export default [{
path: '/page-one/index',
component: () => import('./index'),
meta: {
title: 'page-one-index'
}
}, {
path: '/page-one/sub-page',
component: () => import('./sub-page'),
meta: {
title: 'page-one-sub-page'
}
}];
// page-two-routes.js
// page-two管理的路由文件
export default [{
path: '/page-two/index',
component: () => import('./index'),
meta: {
title: 'page-two-index'
}
}]
上面的page-one
、page-two
两个模块是拆分出来的路由管理文件,下面的js是聚合这两个模块的总路由管理文件。
// root-router.js
// 总路由管理文件
let routes = [];
[
'page-one',
'page-two'
].forEach(m => routes = routes.concat(require(`./pages/${m}/router`).default));
export default new VueRouter({ routes });
到这里,这个优化看起来已经好多了,有新增的业务只需要新增业务对应的router.js
文件,然后再将业务注册到root-router.js
即可。但是我们能不能再优化呢,当前方案再每次新增的时候,都需要改两个地方;答案是肯定的,我们还可以优化。
自动化方案
Webpack4中提供了require.context()
以通过正则匹配引入对应的模块
require.context(directory, useSubdirectories = false, regExp = /^\.\//);
- directory:检索的目录
- useSubdirectories:是否检索子目录
- regExp:匹配文件的正则表达式
具体的介绍可以参考官方文档
所以我们可以修改root-router.js
`路由加载的逻辑如下:
let routes = [];
// auto import route.js
(modules => modules.keys().forEach((key) => {
routes = routes.concat(modules(key).default);
}))(require.context('./pages/', true, /router\.js$/));
export default new VueRouter({ routes });
当有新的页面添加时,只需要在其子目录中添加router.js
文件,root-router.js
文件将会自动将其关联。
思考
虽然这只是一个小小的优化,但是在优化过程中体现了工程化的一个目的,就是尽量减少人工操作,降低维护成本。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。