动态路由:实际路径和路由参数路径匹配

文章讲述了在Vue.js应用中,如何处理动态路由权限的问题。当用户无权访问特定页面时,系统会显示无权限提示并重定向到首页。实现这一功能主要通过全局路由前置守卫和`router.getRoutes()`结合自定义的`matchPath`函数或`path-to-regexp`库进行路由匹配。在用户刷新动态路由页面时,会先检查路由列表确保权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景

1、目前存在页面是动态路由权限,当用户没有项目页面权限,从漏洞页面有push到项目页面的函数,
	点击会直接到首页(根据路由匹配 {  path: '*', redirect: '/' })
	
2、目前我们想做的是在跳转过去的时候添加一个 无权限的提示
	Message.error('当前页面无权限'),然后再跳转到首页

3、思路:
	进入路由时,查看当前进入的页面路由是否在路由列表中存在
4、方法:
	全局路由前置守卫+router的api(getRoutes())
5、注意事项:
	我们只能根据path路径进行对比
	原因由于是addroute添加的动态路由,当我们在动态路由页面刷新时,第一次路由守卫还没有添加动态路由,
	获取的不到route的name等数据,如下图

在这里插入图片描述

实现

1、去除默认匹配规则

// 项目去除掉以下代码 我们在全局守卫中自己实现跳转
{  path: '*', redirect: '/' }

2、全局路由前置守卫中对当前路由进行匹配判断

封装路由匹配函数:
比如 path:'/role/detail/2'和route:'/role/detail/:id'  比较(返回true)
function matchPath(path: any, route: any) {
    const pathParts = path.split('/')
    const routeParts = route.split('/')

    if (pathParts.length !== routeParts.length) {
      return false
    }

    for (let i = 0; i < routeParts.length; i++) {
      if (routeParts[i] === '*') {
        return true
      } else if (routeParts[i].startsWith(':')) {
        // Handle path parameters
        continue
      } else if (pathParts[i] !== routeParts[i]) {
        return false
      }
    }

    return true
  }

匹配判断


let reloadNum = 0


router.beforeEach(async (to: any, from: any, next: any) => {
  Nprogress.start()
  if (!getToken() && !isWhiteList(to.path)) {
    next('/login')
    return
  }
  if (!getToken() && isWhiteList(to.path)) {
    next()
    return
  }
  // 获取动态路由
  if (getToken() && !store.getters.userInfo) {
    try {
      await store.dispatch('user/getUserInfo')
      // 这一步是在vuex中调取了当前的动态路由,实现router.addrouters
    } catch (e) {
      await store.dispatch('user/logOut')
    }
  }
  console.log('动态路由页面刷新,由于路由重制,addroute刚添加', to)


  // 判断当前路由path和route是否相等!!!!
	// 这一步放在动态路由添加后
	// 1、获取当前用户完整的路由列表
  const routerArr = router.getRoutes()
  // 2、判断当前进入的页面to.path是否在路由列表中
  const routerIndex = routerArr.findIndex((item: any) => {
    return matchPath(to.path, item.path)
  })
  if (routerIndex === -1) {
  	// 中英文提示无权限
    Message.error(i18n.t('message.quanxian') as string)
    // 回到首页
    next('/')
    return
  }
  if (getToken() && to.path === '/login') {
    next({ name: 'dashboard' })
    return
  }
  if (getToken()) {
    if (reloadNum) {
      next()
    } else {
      reloadNum++
      next({ ...to, replace: true })
    }
    return
  }
})

方法二:使用path-to-regexp

简单介绍
在vue-router中,react-router或koa-router中,我们经常做路由匹配像这种格式的 /foo/:id 这样的,
或者其他更复杂的路由匹配,都能支持,那么这些路由背后是怎么做的呢?
其实它就是依赖于 path-to-regexp.js的。

path-to-regexp详细使用参考

import { pathToRegexp } from 'path-to-regexp'
const routerArr = router.getRoutes()
  const routerIndex = routerArr.findIndex((item: any) => {
    return pathToRegexp(item.path).exec(to.path)
    // 匹配正确显示object信息
    // 匹配不到返回null
  })
  if (routerIndex === -1) {
    Message.error(i18n.t('message.quanxian') as string)
    next('/')
    return
  }
<think>首先,用户的问题是:“我想了解Vue路由路径参数匹配顺序请问Vue路由匹配顺序参数路径优先级”。这涉及到VueRouter的匹配机制。从系统级指令中,我有参考站内引用:-引用[1]:VueRouter使用自己的路径匹配语法,支持高级匹配模式,如可选参数、零或多个、一个或多个、自定义正则。匹配优先级。-引用[2]:动态路径参数以/:开头;不同参数映射到相同路由;多段路径参数的值设置到$router.params中。用户的核心是“匹配顺序”“优先级”,特别是参数路径的优先级。关键点:-VueRouter的匹配基于路由定义顺序。它从上到下遍历路由配置,直到找到第一个匹配路由。-路径参数(如/user/:id)是动态的,匹配任何值,但静态路径(如/user/profile)有更高优先级。-优先级规则:1.静态路径(如/about)优先级最高。2.参数动态路径(如/user/:id)。3.通配符路径(如/*),优先级最低。在匹配时:-VueRouter检查路径是否精确匹配静态部分。-如果有参数,它会捕获值并继续匹配。-顺序在路由配置数组中很重要:先定义的优先级更高。例如:-如果有两个路由:{path:'/user/profile'}{path:'/user/:id'},当访问/user/profile时,它会匹配第一个,因为静态路径优先。-如果访问/user/123,它会匹配第二个。其他高级特性:-可选参数:使用/:param?表示可选。-正则匹配:在参数中使用正则表达式约束。我需要用中文回答,结构清晰。回答应包括:1.解释匹配顺序的基本原理。2.讨论优先级规则。3.给出例子。4.生成相关问题。最后,添加引用标识,如[^1],引用提供的参考。回答结构:-先概述VueRouter的匹配机制。-然后详细说明顺序优先级。-使用例子说明。-最后生成相关问题。确保使用LaTeX格式:-行内数学表达式用$...$,但这里可能不需要数学,除非有方程。-独立公式用$$...$$,同样可能不适用。-使用中文。生成相关问题:-基于主题,提出一些相关问题。相关问题想法:1.VueRouter中如何定义动态路由参数?2.如何处理嵌套路由匹配顺序?3.通配符路由的使用场景优先级?4.如何优化路由匹配性能?现在,构建回答。</think>### Vue 路由路径参数匹配顺序与优先级 在 Vue Router 中,路由匹配顺序优先级是核心机制,它决定了当用户访问一个 URL 时,哪个路由规则会被激活。匹配过程基于路由配置数组的顺序路径语法规则,优先级从高到低依次为:**静态路径 > 动态参数路径 > 通配符路径**。以下是详细解释: #### 1. **基本匹配顺序原理** - Vue Router 按照路由配置数组中定义的**顺序从上到下遍历**,一旦找到第一个匹配路由规则,就停止匹配[^1]。例如: ```javascript const routes = [ { path: '/user/profile', component: Profile }, // 静态路径,优先级高 { path: '/user/:id', component: User }, // 动态参数路径 { path: '/:catchAll(.*)', component: NotFound } // 通配符路径,优先级最低 ]; ``` - 访问 `/user/profile` 时,匹配第一个路由(静态路径)。 - 访问 `/user/123` 时,匹配第二个路由动态参数路径)。 - 访问 `/unknown` 时,匹配第三个路由(通配符路径)。 - **动态参数路径**以 `/:` 开头(如 `/user/:id`),能匹配任意值(如 `/user/foo` 或 `/user/bar`),但优先级低于静态路径[^2]。 #### 2. **优先级规则详解** - **静态路径优先**:完全匹配的静态路径(如 `/about`)优先级最高,因为它们是精确的。 - **动态参数路径次之**:带参数路径(如 `/user/:id`)会捕获值并存储到 `$route.params` 中。如果有多个动态段(如 `/user/:userId/post/:postId`),所有参数值都会映射到 `$route.params`[^2]。 - **通配符路径最低**:使用 `*` 或 `:catchAll(.*)` 的通配符路径(如 `/*`)匹配剩余路径,但仅在无更具体匹配时生效。 - **高级匹配特性**: - **可选参数**:使用 `/:param?` 语法(如 `/user/:id?`),可匹配 `/user` 或 `/user/123`。 - **正则约束**:在参数中添加正则表达式(如 `/user/:id(\\d+)`)限制匹配格式(仅数字)。 - 这些特性支持复杂场景,但优先级仍遵循静态 > 动态 > 通配符的层级[^1]。 #### 3. **示例说明** - **场景 1:静态 vs 动态优先级** - 路由配置: ```javascript routes: [ { path: '/product/list', component: ProductList }, // 静态 { path: '/product/:id', component: ProductDetail } // 动态 ] ``` - 访问 `/product/list`:匹配第一个路由(静态优先)。 - 访问 `/product/123`:匹配第二个路由。 - **场景 2:动态参数捕获** - 路径 `/user/:userId/post/:postId` 访问 `/user/evan/post/123`: - `$route.params` 为 `{ userId: 'evan', postId: '123' }`[^2]。 - 如果同时存在 `/user/admin`(静态),则 `/user/admin` 优先于 `/user/:userId`。 #### 4. **匹配优化建议** - **配置顺序**:将具体路由(如静态路径)放在数组顶部,通用路由(如通配符)放在底部。 - **避免冲突**:使用正则约束限制参数范围(如 `/:id(\\d+)` 只匹配数字),减少歧义。 - **性能影响**:简单路由匹配高效,但复杂正则可能影响性能;在大型应用中,合理分组路由可提升速度[^1]。 Vue Router 的路径匹配机制灵活强大,灵感来源于 Express.js,支持多种高级模式,但核心优先级规则保持一致[^1][^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值