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前端网发表,如需转载,请注明页面地址。
code前端网




发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。