Skip to content

动态路由

uni-simple-router 中,你可以使用动态路由来实现根据不同的条件生成和注册路由。动态路由允许你根据需要在运行时动态添加、修改或删除路由配置。

添加路由

通常情况下我们会在构建路由实例时,通过传递 routes 参数来定义初始的路由表。但在某些情况下,我们可能需要在运行时动态地添加或删除路由。为了实现动态路由的功能,uni-simple-router 提供了两个函数:router.addRoute()router.removeRoute()

使用 router.addRoute() 可以动态地添加一个新的路由到路由表中。需要注意的是,添加的新路由只是注册在路由表中,如果新增的路由与当前的路径匹配,需要使用 router.push()router.replace() 方法手动进行导航,以显示该新路由。

想象一下,只有一个动态路由表的情况下:

js
const router = createRouter({
  // 其他配置
  routes: [{ path: '/:articleName', component: Article }],
})

进入任何页面,/about/store,或者 /3-tricks-to-improve-your-routing-code 最终都会呈现 Article 组件。如果我们再添加一个新的路由 /about

js
router.addRoute({ path: '/about', component: About })

页面仍然会显示 Article 组件,我们需要手动调用 router.replace() 来改变当前的位置,并覆盖我们原来的位置,像下面这样:

js
router.addRoute({ path: '/about', component: About })
// 我们也可以使用 this.$Route 或 route = useRoute() (在 setup 中)
router.replace(`/about`)

记住,如果你需要等待新的路由显示,可以使用 await router.replace()

在导航守卫中添加路由

如果你决定在导航守卫内部添加或删除路由,你不应该调用 router.replace(),而是通过返回新的位置来触发重定向:

下面是一个示例,展示如何在导航守卫中添加路由:

js
import {
    createRouter,
    __dynamicImportComponent__
} from '@/uni-simple-router'

// 动态添加路由的路由表
const dynamicRoute = {
  path: '/dynamic',
  name: 'DynamicRoute',
  component: __dynamicImportComponent__(`@/views/DynamicRoute.vue`,{
    pageType: `top`
  })
};

const router = createRouter({
  routes: [
    // 初始路由配置
    // ...
  ],
});

router.beforeEach((to, from) => {
  // 判断是否需要添加路由
  if (!hasNecessaryRoute()) {

    // 添加路由配置
    router.addRoute(dynamicRoute);

    // 执行导航,确保新路由生效
    return {
      ...to,
      name: 'DynamicRoute',
      navType:`replace`
    };
  } 
  // 继续正常导航
});

export default router;

如果你是在导航守卫中添加路由表,需要避免无限重定向,可以先判断是否已经添加了需要的路由表,以避免重复添加。

因为是在重定向中,所以我们需要替换将要跳转的导航,实际上行为就像之前的例子一样。而在实际场景中,添加路由的行为更有可能发生在导航守卫之外,例如,当一个视图组件挂载时,它会注册新的路由。

删除路由

有几个不同的方法来删除现有的路由:

  • 通过添加一个名称冲突的路由。如果添加与现有路由表名称途径相同,会先删除路由,再添加路由:
js
router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })
  • 通过调用 router.addRoute() 返回的回调:
js
const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话 成功返回 true 识别返回false

当路由没有名称时,这很有用。

  • 通过使用 router.removeRoute() 按名称删除路由:
js
router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')

需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。

陷阱提示

  • 如果删除的路由时父级路由时,它所有的别名和子路由也会被同时删除。

添加嵌套路由

要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 router.addRoute(),这将有效地添加路由,就像通过 children 添加的一样:

js
router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })

这等效于:

js
router.addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin,
  children: [{ path: 'settings', component: AdminSettings }],
})

引入分包中的组件

在使用动态添加路由表时,有时你可能需要引入其他分包下的组件作为页面组件进行渲染。在 uni-simple-router 中,插件已经在内部实现了这个逻辑,允许你这样做。

然而,在小程序中,需要注意平台的支持度。不同的小程序平台可能对于在分包中使用动态引入组件的方式有所限制或差异,因此在使用该功能时,请参考在分包中使用

动态路由 has loaded