pekonchan/Blog

如何写出一个利于扩展的vue路由配置

Opened this issue · 0 comments

前言

从历往经验来看,开发一个新项目,往往在刚开始部署项目,到项目的正式交付,以及交付后的后续维护,功能增强等过程,都需要对项目的一些已有结构和逻辑进行调整。

因此,如果有些内容刚建项目时不考虑好未来的可扩展性,后续调整会很麻烦。

这里先来说,在vue项目中,如何写路由配置,更利于未来可扩展。

vue-router的基本配置

为了方便新学者的阅读与理解。先来看一下最基本的路由是如何配置的

// 0. 导入Vue和VueRouter脚本,如果使用模块化机制编程,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定义路由
// 每个路由应该映射一个组件。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

如果具体还要什么不懂的,还是多看 官方文档

便于扩展的路由设置

到这里我当你已经比较熟悉路由配置的相关知识哦,很细的知识点我就不细说了。

场景1

假设你现在接到一个新项目,产品经理要求你开发一个系统,给你的交互图等资料都是关于系统内部的各个页面。 这时你以为开发的这个系统就仅仅是直接展示系统内部的情况了,甚至你啥都没想,就直接开始配置路由写页面去了。

一开始你差不多写出了以下的路由配置:

// example 1
const router = new VueRouter({
    routes: [
        { path: '/page1', component: Page1 },
        { path: '/page2', component: Page2 }
    ]
});

像这种配置的,大概就猜出你把系统的菜单等公共部分都放在App.vue里写好了,然后通过一个<router-view/>进行系统内容的变更。

场景2

后面产品经理跟你说,要系统加一个官网、首页之类的存在。!!如果你配了按照上述的路由情况,此时,你是不是有点懵呢?因为你把系统的公共内容如菜单都写在App.vue上了,但是首页不需要系统的这些部分。

尽管你再配出了一个首页的路由,但是你也要想办法去掉那些已有的系统公共部分。

解决方案

所以我们不能采用上述配置方式。此时我们应该把系统本身作为一个路由,系统公共部分写在这个路由映射组件上,而系统内部各页作为子路由,嵌套在其下。

// example 2
const router = new VueRouter({
    routes: [
        { 
            path: '/'
            component: Main,
            children: [
                {
                    path: 'page1',
                    component: Page1
                },
                {
                    path: 'page2',
                    component: Page2
                }
            ]
        }
    ]
});

这里的Main组件就是系统的入口,菜单等公共部分就是写在这里

此时App.vue文件的内容应该就直接是一个路由入口了

<!-- App.vue -->
<template>
    <div>
        <router-view/>
    </div>
</template>

如果你一开始是这么写的话,那么要新增一些非系统内部的页面,简直就轻而易举了。如新增个首页,直接新增个一级路由就好了

// example 3
const router = new VueRouter({
    routes: [
        { 
            path: '/'
            component: Main,
            children: [...]
        },
        { 
            path: '/home'
            component: Home
        }
    ]
});

但是此时我们应该要知道,当仅输入你的网站域名(没有具体到哪页)时,会默认打开path: /的页面,上述例子就是默认打开系统页面了。

场景3

你的产品经理又来找事啦。再要求你添加个非系统页,如登录注册页,打开网站地址域名时默认跳转到登录页。

嗯,按照上一个配置情况,新增一个登录页简直so easy,但是要改默认打开页,这就尴尬了。

有人说,直接把系统的那个一级路由改一下不就好了嘛,然后把path: /留给要求默认打开的页面。

嗯,你说的很有道理,但我,不听!假设你系统里有比较多的跳转,从系统内某一页跳转到某一页的情况多,即你已经在代码里写了很多个$router.push('xxxx'),如果这么一改,很麻烦,要一个个找出来进行修改。

解决方案

因此,我们一开始的时候,就不应该为系统页直接占用path: '/'的路由。但是也不能为目前已知的任何一个页面占用path: '/',因为即使你现在明确哪个页面是默认打开页,但是你不能保证你的产品经理不会变心啊,万一后面又要改呢?

所以!我们要为目前已知的每个页面都设置路径名,而不能占用path: '/';而实现默认打开的功能,就要利用redirect进行跳转

// example 4
const router = new VueRouter({
    routes: [
        { 
            path: '/main'
            component: Main,
            children: [...]
        },
        { 
            path: '/home'
            component: Home
        },
        {
            path: '/login',
            component: Login
        },
        {
            path: '/',
            redirect: '/login'
        }
    ]
});

这样的话,不论后面怎么变化,你只需要做新增/删除路由 以及 改变redirect值控制打开默认页了。这就是最终的解决方案了

优化路由结构内容

还是在上一个例子结论的基础上进行这节的描述,假设你的系统比较大,有很多的页面,很多的模块,例如菜单栏中有比较多的一级菜单,而每个一级菜单下又有很多二级菜单甚至子孙菜单。

好,就算你现在拿到的需求是很少系统内容的,但是你也不能保证以后你的系统会发展成什么样,万一卖得很好,加很多功能需求呢。

在上述假设的条件下,那么你就得往children里加很多路由映射了

{ 
    path: '/main'
    component: Main,
    children: [...]
}

如此一来,你的这个文件,必定很长很长!因此,我们要拆分,进行模块化引入。

可以以你一级菜单的名字命名进行模块拆分,一个一级菜单对应一个文件(如果你的系统有功能模块的区分,那也可以按照功能模块来拆分文件),然后引入到这个主路由配置文件即可。

// example 5
...
import overview from './overview';
import copyrightManager from './copyrightManager';
import monitor from './monitor';

const router = new VueRouter({
    routes: [
        { 
            path: '/main'
            component: Main,
            children: [
                {
                    path: '',
                    // 默认进入的系统内部页
                    redirect: 'overview'
                },
                ...overview,
                ...copyrightManager,
                ...monitor
            ]
        },
        { 
            path: '/home'
            component: Home
        }
    ]
});

这里例子中就是把原本写在children里边的一个个路由映射单独写在每个文件里(自己分类好),然后通过import引进来,利用...再把它放回进去。

这样维护起来就更加方便啦

总结

关于路由的配置优化介绍就说到这里了,喜欢的话请点个赞吧。