美文网首页
vue-router如何去中心化

vue-router如何去中心化

作者: FiveYet | 来源:发表于2019-04-10 11:09 被阅读0次

    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个需求都开发完了,准备继续后续的测试->发布流程。
    image

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

    如何解决

    • 模块化
    • require.context

    1. 模块化

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

    image

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

    // 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 来指定一系列完整的依赖关系,便于更细粒度的控制模块引入。

    文档地址:https://webpack.js.org/guides/dependency-management/#requirecontext

    简单来说,通过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在编译构建时去分析,从而解除依赖。

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

    相关文章

      网友评论

          本文标题:vue-router如何去中心化

          本文链接:https://www.haomeiwen.com/subject/hxfniqtx.html