Vue Router(2)

带参数的动态路由匹配

很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染, 但用户ID不同。在Vue Router中,我们可以在路径中使用一个动态字段来实现,我们称之为路径参数

复制代码
const User = {
     template: '<div> User </div>'
}

// 这些都会传递给 `createRouter`
const routers = [
   // 动态字段以冒号开始
   { path: '/users/:id', component: User}
]
复制代码

现在像 /users/johnny 和 /users/jolyne 这样的URL都会映射到同一个路由

 

路径参数 用冒号 : 表示, 当一个路由匹配时, 它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。因此,我们可以通过更新Userd的模板来呈现当前用户ID

const User = {
  template: '<div>User {{ $route.params.id }}</div>',
}

 

你可以在同一个路由中设置有多个路径参数, 它们会映射到 $route.params 上的相应字段。

例如:

/users/:username    // /users/eduardo    {username: 'eduardo'}

/users/:username/posts/:postId   // /users/eduardo/posts/123  {username: 'eduardo', postId:'123'}

 

除了 route.paramsroute 对象还公开了其他有用的信息,如 route.query(URL)route.hash 等。

 

响应路由参数的变化

使用带有参数的路由时需要注意的时,当用户从 /users/johnny 导航到  /users/jolyne时 ,相同的组件实例将被重复使用。因为两个路由都渲染同一个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会被调用。

 

要对同一个组件中参数的变化做出响应的话,你可以简单地 watch routeroute.params.

复制代码
const User = {
  template: '...',
  created() {
    this.$watch(
      () => this.$route.params,
      (toParams, previousParams) => {
        // 对路由变化做出响应...
      }
    )
  },
}
复制代码

或者,使用 beforeRouteUpdate 导航守卫, 它也可以取消导航:

const User = {
  template: '...',
  async beforeRouteUpdate(to, from) {
    // 对路由变化做出响应...
    this.userData = await fetchUser(to.params.id)
  },
}

 

捕获所有路由或 404 Not found路由

常规参数只匹配 url 片段之间的字符, 用 / 分隔。 如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式

const routes = [
  // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  { path: '/user-:afterUser(.*)', component: UserGeneric },
]

 

在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将 pathMatch 参数标记位可选可重复。这样做时为了让我们在需要的时候,可以通过将 path 拆分成数组,直接导航到路由:

this.$router.push({
  name: 'NotFound',
  params: { pathMatch: this.$route.path.split('/') },
})

 

大多数应用都会使用 /about 这样的静态路由和 /users/:userId 这样的动态路由。想象一下,两个路由 /:orderId 和 /:productName,两者会匹配完全相同的URL,所以我们需要一种方法来区分它们。

(1)、添加静态部分

const routes = [
  // 匹配 /o/3549
  { path: '/o/:orderId' },
  // 匹配 /p/books
  { path: '/p/:productName' },
]

    (注:确保转义反斜杠(\) 

(2)、在括号中为参数指定一个自定义的正则

const routes = [
  // /:orderId -> 仅匹配数字
  { path: '/:orderId(\\d+)' },
  // /:productName -> 匹配其他任何内容
  { path: '/:productName' },
]

 

可重复的参数

如果你需要匹配具有多个部分的路由, 如  /first/second/third, 你应该用 * (0 个 或 多个) 和 + (1个或多个)将参数标记为可重复:

const routes = [
  // /:chapters ->  匹配 /one, /one/two, /one/two/three, 等
  { path: '/:chapters+' },
  // /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
  { path: '/:chapters*' },
]

 

复制代码
// 给定 { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 产生 /
router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
// 产生 /a/b

// 给定 { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 抛出错误,因为 `chapters` 为空 
复制代码

 

const routes = [
  // 仅匹配数字
  // 匹配 /1, /1/2, 等
  { path: '/:chapters(\\d+)+' },
  // 匹配 /, /1, /1/2, 等
  { path: '/:chapters(\\d+)*' },
]

 

posted on   zhishiyv  阅读(53)  评论(0编辑  收藏  举报

(评论功能已被禁用)
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端

导航

统计

点击右上角即可分享
微信分享提示