3

前言

本文启发自实际项目中,随着项目不断增长,页面越来越多,不得不把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-onepage-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文件将会自动将其关联。

思考

虽然这只是一个小小的优化,但是在优化过程中体现了工程化的一个目的,就是尽量减少人工操作,降低维护成本。


Jackie
122 声望4 粉丝