vue router怎么获取url?
做Vue项目时,经常需要和当前页面的URL“打交道”——比如判断用户进了哪个页面、从URL里抠参数发请求、根据搜索关键词展示内容…但Vue Router的URL信息藏在哪?不同场景(组件内、组件外、动态路由、查询参数)咋获取?这篇从基础到实战,把常见情况拆明白~
组件里咋拿到当前路由信息?
先分Vue2和Vue3两种情况(毕竟API有差异),核心是用路由实例提供的“路由对象”,里面存着当前URL的所有信息~
Vue3(组合式API):用 useRoute
在组件的<script setup>
里,先导入useRoute
,它会返回一个响应式的路由对象(能自动跟踪路由变化),路由对象里有这些关键属性:
path
:当前路径(不含查询参数、哈希,比如/user/123
)params
:动态路由参数(后面讲动态路由时细说)query
:查询参数(后面的部分,比如?name=jack
对应{name: 'jack'}
)fullPath
:完整URL(包含路径、查询、哈希,比如/user/123?name=jack#info
)name
:路由配置里的name
(如果配了的话)
举个实际例子,假设当前URL是/product/1001?tab=detail
,组件里这么写:
<template> <div> 路径:{{ route.path }} → 输出 /product/1001<br> 完整路径:{{ route.fullPath }} → 输出 /product/1001?tab=detail<br> 动态参数:{{ route.params }} → 输出 {productId: '1001'}(假设路由是/product/:productId)<br> 查询参数:{{ route.query.tab }} → 输出 detail </div> </template> <script setup> import { useRoute } from 'vue-router' // 从vue-router导入useRoute const route = useRoute() // 获取路由对象 </script>
Vue2(选项式API):用 this.$route
在Vue2的组件里,不需要额外导入,直接通过this.$route
访问路由对象,属性和Vue3的route
一致。
<template> <div>当前路径:{{ $route.path }}</div> </template> <script> export default { mounted() { console.log(this.$route.query) // 打印查询参数对象 } } </script>
动态路由参数咋提取?
动态路由是指URL里带变量的部分,比如用户详情页需要根据不同用户ID跳转,路由配置成path: '/user/:userId'
(:userId
就是动态参数),这时候要从URL里把userId
抠出来~
步骤:路由配置→组件里拿参数
- 先在路由规则里定义动态参数:
const routes = [ { path: '/user/:userId', // :userId是动态参数 component: UserDetail } ]
- 组件里通过
route.params.参数名
获取:
Vue3写法:<script setup> import { useRoute } from 'vue-router' const route = useRoute() const userId = route.params.userId // 当URL是/user/666时,userId就是'666' </script>
Vue2写法:
export default { mounted() { const userId = this.$route.params.userId } }
特殊情况:可选参数、正则限制
- 可选参数:如果参数可传可不传,路由配置写成
path: '/user/:userId?'
,此时route.params.userId
可能是undefined
(没传的时候)。 - 正则限制:想让参数只能是数字?路由配置写成
path: '/user/:userId(\\d+)'
,这样只有当userId
是数字时,路由才匹配(比如/user/123
有效,/user/abc
无效)。
查询参数(?xxx=yyy)咋获取?
查询参数是URL中后面的键值对(比如/search?keyword=vue&page=2
),这部分信息存在route.query
里,它是个对象,键是参数名,值是参数值~
基本用法
假设当前URL是/search?keyword=vue&page=2
,组件里:
Vue3:
<script setup> import { useRoute } from 'vue-router' const route = useRoute() const keyword = route.query.keyword // 输出 'vue' const page = Number(route.query.page) // 输出 2(转成数字) </script>
Vue2:
export default { mounted() { console.log(this.$route.query.keyword) // 输出 'vue' } }
多值参数处理
如果URL是/tags?tag=js&tag=vue
(同一个参数传多个值),route.query.tag
会变成数组['js', 'vue']
,处理时要注意类型,
const tags = Array.isArray(route.query.tag) ? route.query.tag : [route.query.tag] // 确保是数组,方便后续遍历
非组件环境咋拿路由信息?
有时候不在组件里(比如路由守卫、单独的工具函数),也要获取URL信息,这时候得换方法~
路由守卫里:用to
和from
全局守卫(比如beforeEach
)、组件内守卫(比如beforeRouteEnter
)会传入to
和from
两个参数,它们都是路由对象,和$route
结构一样~
举个全局守卫的例子(判断用户权限):
router.beforeEach((to, from) => { console.log('要进入的页面:', to.path) // /admin console.log('从哪个页面来:', from.fullPath) // /home?tab=news // 假设只有管理员能进/admin if (to.path === '/admin' && !isAdmin()) { return '/login' // 没权限就跳登录页 } })
组件内守卫(Vue2的beforeRouteEnter
):
export default { beforeRouteEnter(to, from, next) { console.log('要进入的页面参数:', to.params.id) next() // 必须调用next()放行 } }
单独JS文件里:导入router实例
如果在工具函数、自定义插件里需要路由信息,得先导入项目里创建的router
实例,再通过currentRoute
获取~
Vue3中,router.currentRoute
是响应式对象(用ref
包着),所以要取value
:
// 假设router.js里导出了router实例 import router from './router' function getCurrentPage() { return router.currentRoute.value.path // 获取当前路径 }
Vue2中,router.currentRoute
直接是路由对象:
import router from './router' console.log(router.currentRoute.path) // 直接拿路径
path和fullPath有啥区别?啥时候用?
很多人分不清path
和fullPath
,其实它们的核心区别是是否包含查询参数和哈希:
path
:只包含“路由路径 + 动态参数”(比如/user/123
)。fullPath
:包含完整的URL(路径 + 查询参数 + 哈希,比如/user/123?name=jack#info
)。
用的场景举例
- 导航栏高亮:判断“当前是否是首页”,用
path === '/'
就够(不管有没有查询参数,只要路径是/就高亮)。 - 分享链接:需要把用户当前的完整URL发出去,就得用
fullPath
(比如用户在/search?keyword=vue
,分享链接要包含查询参数)。 - 埋点统计:记录用户的完整访问路径,
fullPath
更准确。
实战:根据URL参数加载数据
光说不练假把式,举两个常见场景,看怎么用URL参数干活~
场景1:文章详情页(动态路由参数)
需求:用户访问/article/1001
时,用1001
这个文章ID请求接口,渲染文章内容。
步骤:
- 配置动态路由:
const routes = [ { path: '/article/:articleId', component: ArticleDetail } ]
- 组件内获取参数并请求:
<template> <div v-if="article"> <h1>{{ article.title }}</h1> <p>{{ article.content }}</p> </div> </template>
场景2:列表页分页(查询参数)
需求:用户访问/list?page=2&size=10
时,用page
和size
做分页请求。
组件里这么写:
<template> <div> <ul> <li v-for="item in list" :key="item.id">{{ item.name }}</li> </ul> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { useRoute } from 'vue-router' import { getList } from '@/api/list' // 假设的接口函数 const list = ref([]) const route = useRoute() // 处理查询参数(转成数字,设置默认值) const page = Number(route.query.page) || 1 const size = Number(route.query.size) || 10 onMounted(async () => { const res = await getList(page, size) // 发分页请求 list.value = res.data }) </script>
常见问题&避坑指南
Vue2和Vue3 API别搞混
- Vue3组合式API:必须用
useRoute
(从vue-router
导入)。 - Vue3选项式API:可以用
this.$route
(和Vue2一样)。 - Vue2:只能用
this.$route
。
路由变化时,组件没销毁咋更新数据?
比如动态路由参数变了(/user/1
→ /user/2
),组件会复用(不销毁重建),这时候onMounted
不会重新执行!得用watch监听路由变化:
Vue3写法:
<script setup> import { watch } from 'vue' import { useRoute } from 'vue-router' const route = useRoute() watch(() => route.params.id, (newId) => { // newId变化时,重新请求数据 fetchData(newId) }, { immediate: true }) // immediate:页面加载时也执行一次 function fetchData(id) { /* ... */ } </script>
Vue2写法:
export default { watch: { '$route.params.id'(newId) { this.fetchData(newId) } }, methods: { fetchData(id) { /* ... */ } } }
别直接修改$route!
$route
是只读对象,想改URL只能用router.push
、router.replace
这些方法,比如想跳转到新页面,得写:
import { useRouter } from 'vue-router' const router = useRouter() router.push('/new-path') // 正确 // this.$route.path = '/new-path' → 错误!会报错
Vue Router获取URL信息的核心是「路由对象」($route或useRoute返回的对象),不同场景下(组件内、组件外、动态路由、查询参数)的获取方式略有不同,但只要抓住「路由对象的属性」和「API版本差异」这两个点,就能轻松应对~ 下次遇到URL相关的需求,直接对应场景挑方法用就好啦~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。