实现全屏页面跳转:Vue Router 嵌套路由的灵活用法

311 阅读3分钟

问题及背景

背景

Vite + Vue3 项目,想要实现如下图的效果:

image

父页面有几个按钮,跳转到子页面;子页面可以返回到父页面。

问题

交互很简单,但是父页面和子页面都是全屏展示,一样的大小,它们之间没有共用的逻辑和布局,比如菜单。所以可以把父页面、子页面当做没有关联的独立的页面。

Vue Router 常规路由

常规的一级路由,路由信息:

{
  path: '/home',
  name: 'Home',
  component: () => import('@/views/Home'),
},
{
  path: '/page1',
  name: 'Page1',
  component: () => import('@/views/Page1'),
},
{
  path: '/page2',
  name: 'Page2',
  component: () => import('@/views/Page2'),
},

父页面和子页面是同级的路由,它们在路由上没有嵌套的关系,这样是能实现页面跳转的。

Vue Router 二级嵌套路由

一般的嵌套路由是这样的:

{
  path: '/home',
  name: 'Home',
  redirect: '/home/page1',
  component: () => import('@/views/Home'),
  children: [
    {
      path: 'page1',
      name: 'Page1',
      component: () => import('@/views/Home/Page1'),
    },
    {
      path: 'page2',
      name: 'Page2',
      component: () => import('@/views/Home/Page2'),
    },
  ],
},

它实现的效果是这样的:

image

子页面是父页面的一部分,需要在父页面写 <router-view /> 引入子页面。

注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。

这里 children 里的 path 没有以 / 开头,得到的子页面路由就是:/home/page2 这样,如果以 / 开头,得到的页面路由就是:/page1

扁平的二级嵌套路由

官网介绍了一种忽略父路由组件的用法,用法如下:

const routes = [
  {
    path: '/admin',
    children: [
      { path: '', component: AdminOverview },
      { path: 'users', component: AdminUserList },
      { path: 'users/:id', component: AdminUserDetails },
    ], 
  },
]

父路由不写 component,子路由中 path 为空的路由组件就渲染了父路由,其他路由和正常的嵌套路由一样。

Vue router 会直接跳过父路由,不渲染任何父组件,只加载匹配的子路由组件。

这样的做的好处有:

  • 组织路由结构:将具有公共路径前缀的路由分组在一起
  • 公共配置:为一组路由(子路由)配置公共的功能(meta 字段或导航守卫)

受这种用法的启发,我们前面问题的路由可以这样设置:

{
  path: '/home',
  children: [
    {
      path: '',
      name: 'Home',
      component: () => import('@/views/Home/Home'),
    },
    {
      path: 'page1',
      name: 'Page1',
      component: () => import('@/views/Home/Page1'),
    },
    {
      path: 'page2',
      name: 'Page2',
      component: () => import('@/views/Home/Page2'),
    },
  ],
},

父页面并非没有任何内容,只是把父页面当成一个子页面,用子路由来渲染。这样相比一级路由能更好的组织路由结构,Home 中不用写 <router-view />,父路由做的是逻辑分组,而不是 UI 分组,父路由实际上也是有子路由渲染的。

这种路由方法或许可以叫做无组件嵌套路由、或者逻辑嵌套路由、或者扁平的嵌套路由。

这样做的好处

难道这样组织路由的好处只是更好的组织路由路径,更像一个二级嵌套关系而已吗?其他的路由守卫什么的暂时用不到。

实际上,我的菜单数据需要根据路由信息生成,其中的二级菜单也有对应的处理。应用上面的写法,即使特殊形式的二级页面,也不需要修改对菜单的处理。如果是一级路由形式,则需要手动处理一级二级页面的对应关系,处理菜单数据生成、

总结

在 Vue Router 中,灵活的路由结构可以大大提升项目的可维护性和可扩展性。通过扁平的二级嵌套路由,我们能够更好地组织路由,同时保持页面的独立性。这种方式不仅简化了路由的管理,还使得菜单生成逻辑更加清晰。