vue-router是一个与vue核心深度集成的前端路由框架。路由这个词对大家来说其实并不陌生,我们用传统的web项目来举个例子。如下图所示,这是一个左侧为菜单,右侧为功能页面的一个首页效果。此时的路由为:投诉举报/我的批次/批次管理/列表。如果我们要实现这样一个效果,会将红框的部分设置为一个<iframe/>标签,然后通过菜单的点击事件去切换iframe的链接,一般来说每一个链接返回的都是一段由服务端通过jsp等模板语言渲染出来的html文本。整个应用根据路由的层级,会形成iframe的树形嵌套。

而前端发展到现在,整个界面已经在vue这样的框架下实现了组件化,并且服务端不再承担将数据渲染为HTML的任务,数据到界面的渲染由vue这种前端框架来完成,服务端只提供rest接口,为前端提供json格式的数据。前端完全组件化后,将形成一个组件树,如下图:

路由功能由传统的页面切换转变为组件的切换,比如点击“列表页面”组件上的新建按钮,会将当前的“列表页面”组件切换为“新建页面组件”。整个应用将不存在页面的切换,也就是所谓的单页应用。vue-router就是一个管理路由,并根据路由状态,切换组件的一个框架。

路由的管理:

vue-router对路由的管理是由一个router对象来完成,其中path对路由进行命名(':'后面代表参数),component指定了<route-view>要切换到的组件,children指定了路由的嵌套关系。

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        { path: 'profiles', component: Profiles},
        { path: 'posts', component: Posts}
      ]
    }
  ]
})

将这个router对象绑定到某个组件上,它将控制该组件及其子组件的路由状态,并且该组件的<router-view>,成为根<router-view>。

const app = new Vue({
  router: router
})

在命名方面,以‘/’开头的path,都视作为根path,也就是说path可以与ui层级不相符。并且vue-router提供了别名功能。如下面/home/foo和/foo是同一个路由状态,即Home>Foo。

routes: [
    { path: '/home', component: Home,
      children: [
        // absolute alias
        { path: 'foo', component: Foo, alias: '/foo' },
        // relative alias (alias to /home/bar-alias)
        { path: 'bar', component: Bar, alias: 'bar-alias' },
        // multiple aliases
        { path: 'baz', component: Baz, alias: ['/baz', 'baz-alias'] }
      ]
    }
]

此外vue-router还提供了灵活的重定向功能,redirect是个函数,意味着你可以对重定向实现一些动态的操作,比如把当前已登录的账号作为参数拼到重定向的path中。

routes: [
  { path: '/a', redirect: to => {
    // 方法接收 目标路由 作为参数
    // return 重定向的 字符串路径/路径对象
  }}
]

路由的切换:

从表面上来看,路由的切换就是一次状态的转变,由a/b/c转变为a/b/d。vue-router将转换的动作及其实现封装为一个push函数,在切换过程中,path的匹配逻辑,以及组件的切换逻辑都由router实现,调用者只需要关注路由的状态,指定一个目标path。

在切换过程中router首先要对目标path进行匹配,以‘/’开头的path,都被作为根path,如下面代码中存在三个根path:/home, /foo, 和/baz。

routes: [
    { path: '/home', component: Home,
      children: [
        // absolute alias
        { path: 'foo', component: Foo, alias: '/foo' },
        // relative alias (alias to /home/bar-alias)
        { path: 'bar', component: Bar, alias: 'bar-alias' },
        // multiple aliases
        { path: 'baz', component: Baz, alias: ['/baz', 'baz-alias'] }
      ]
    }
]

当执行this.$router.push({path: '/xx/xx/xx'})时,会从以上的三个根path开始匹配。path得到成功匹配后,router-view就会按照嵌套层级切换到对应的组件上。比如this.$router.push({path: '/home/foo'}),会切换到Home>Foo这个状态,如下图。当然this.$router.push({path: '/foo'})也是这个结果。

+-----------------------+
| Home                  |
|                       |
|  +-----------------+  |
|  | Foo             |  |
|  |                 |  |
|  |                 |  |
|  +-----------------+  |
|                       |
+-----------------------+

 

HOOK:

路由的切换过程虽然被封装了,但开发者遇到某些情况时,仍然需要在路由切换过程中加入自己的操作,比如每次路由都校验一下权限。vue-route提供了一个hook机制(导航守卫)。hook的作用范围有全局的和局部的,beforeEach和afterEach是全局的,beforeRouteEnter,beforeRouteLeave,beforeRouteUpdate是组件内部的。

此外vue-router还对路由切换的过渡动画效果进行了封装,并且可以动态的设定:

<transition :name="transitionName">
  <router-view></router-view>
</transition>

路由传参:

参数可以在url的path中

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
    }
  ]
})
router.push('/user/admin')

可以在url的query中

const router = new VueRouter({
  routes: [
    { path: '/user', component: User, props: (route) => ({ id: route.query.id }) }
  ]
})
router.push(/user?id=admin)

 

Logo

前往低代码交流专区

更多推荐