vue-router如何去中心化

vue-router作为Vue官方三大套件之一,在日常开发中成为了不可或缺的存在,但是不管多么niubility的框架或组件,在业务场景不断发生改变的同时,不可避免的会出现一些适用性上的问题,这就需要我们去扩展不同的使用场景,以达到业务上的最佳实践。

vue-router使用姿势

按照vue-router官方的使用文档中,我们在配置和使用vue-router的姿势如下:

  • 组件与路由的映射匹配
// router/index.js
const routes = [
    { path: '/home', component: Home },
    { path: '/about', component: About }
]

export default routes
复制代码
  • 挂载router
// main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

import routes from './router/index.js'
const router = new VueRouter({
    routes
});

new Vue({
    el: '#app',
    //让vue知道我们的路由规则
    router: router,
    render: c => c(App),
})
复制代码

ok,现在我们就可以在我们的组件中通过this.$route来操作路由相关属性及方法了。简直so easy!

vue-router的中心化问题

何为中心化?

谈到中心化,我们想到比较多的可能就是区块链。那广义上的中心化如何理解?简单点说,就是在一个体系中某个节点要和另外的节点产生联系,就一定要通过特定的某个节点,这个节点就是一个中心。

vue-router的中心化

刚讲到中心化的概念,那我们可以拿上面vue-router实践的例子来对照一下。 我们在router/index.js中定义或加载所有的路由配置,那这个文件就是这个项目当中唯一的引用路由的节点(中心)。那中心节点会存在什么问题呢?

  1. 文件冲突:尤其是在使用svn这种集中式版本控制服务,没有分支的概念,全部依赖一个远程中心仓库。
  2. 发布故障:试想多人同时修改同一个文件,在发布流程不是非常完善,且相互沟通不顺畅的情况下,容易出现某个正在开发的需求被另一个同样发布中的需求带上线了,但另一个需求的相关依赖并没有上线。导致生产环境编译错误从而引发线上故障。

下面我们用一个比较简单的发布模型来说明。

模拟开发场景:

  1. 2人同时开发一个项目。
  2. 2个需求分别新建了2个router配置。
  3. 现在2个需求都开发完了,准备继续后续的测试->发布流程。

PS: 上述的场景不一定发生,跟对应开发团队的发布流程相关。在开发流程比较完善的情况下是可以避免该问题的。

如何解决

  • 模块化
  • require.context

1. 模块化

可以将路由按业务模块划分场景,对应模块下有一个独立的入口文件,尽可能保证相同业务需求不会出现路由文件冲突的情况。

对应的加载路由的配置可以修改为

// moduleA/index.js
import routeA from './moduleA-xx'
import routeA2 from './moduleA-xx2'
// 在这里扩展moduleA的路由配置
const routes = [].concat(routeA, routeA2)

export default routes
复制代码
// router/index.js
import moduleA from './moduleA/index'
import moduleB from './moduleB/index'

const routes = [].concat(moduleA, moduleB)
复制代码

2. require.context

官方文档的说明是require.context使用 directory 路径、includeSubdirs 选项和 filter 来指定一系列完整的依赖关系,便于更细粒度的控制模块引入。

文档地址:webpack.js.org/guides/depe…

简单来说,通过require.context我们可以通过正则动态匹配并引入我们的依赖文件,这样我们不需要显示的去加载我们的路由文件,从而解耦router的入口文件和对应route配置的依赖关系。在这里我们通过它来实现我们的路由去中心化。

我们约定router目录下所有的.js文件默认都为route的配置文件,通过require.context加载的代码如下。

// 加载router目录下所有js文件作为路由配置
let routes
let matches = require.context('./', true, /^\.\/[^/]+\/.+\.js$/)
matches.keys().forEach(key => {
	routes = routes.concat(matches(key).default)
})
复制代码

这样,以后新增或修改路由只需要按照约定在router目录新建js文件或修改其中的配置即可,router/index.js不需要任何改动即可完成路由配置。

总结

在这里我们总结下对于上述问题的一个解决思路,我们可以把中心化问题看成是一个依赖解耦的问题。那我们便可以用解耦的思路来解决中心化的问题,在上述解决方案中,我们用到了以下手段:

  • 单一职责:模块化拆分路由配置。
  • 依赖倒置:通过约定大于配置的方式将入口文件与路由配置细节解耦,将路由配置的显式加载过程抽象为通过require.context方式加载,具体的执行过程交由webpack在编译构建时去分析,从而解除依赖。

关于解耦的问题,我觉得也是一个可以好好讨论的点,有时间再和大家一起分享分享啦!感谢各位百忙之中抽出时间观看!!!

转载于:https://juejin.im/post/5c990170f265da60ea146bab

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值