Code前端首页关于Code前端联系我们

Vue Router 里的 route 到底是什么?怎么用?常见问题全解答

terry 18小时前 阅读数 15 #Vue
文章标签 Vue Router;route

很多刚接触Vue Router的同学,经常会把route和router搞混,也不太清楚route在项目里到底咋用,今天咱就唠唠Vue Router里route的那些事儿,从基础概念到实际场景,把常见问题一个个掰碎了讲明白~

route 到底是个啥?和 router 有啥区别?

先把最基础的概念理清楚——Vue Router里的 route 指的是当前路由的信息对象,你可以把它理解成“当前页面路由的快照”,里面存着路径、参数、元信息这些关键数据,而 router 是Vue Router的实例,负责干“跳转页面、注册路由、管理整个路由系统”这些活儿。

举个生活里的例子:假设你用导航APP找餐厅,route 就像你当前所在位置的“定位卡片”,上面写着你在哪条路、要去的餐厅ID是多少;而 router 就是整个导航APP,能帮你规划路线、切换目的地、控制导航流程。

在代码里怎么区分?比如Vue2的组件中:

```js export default { mounted() { // route:当前路由信息(路径、参数等) console.log(this.$route.path); // 打印当前路径,'/user/123' // router:路由实例(用来跳转、操作路由) this.$router.push('/home'); // 跳转到首页 } } ```

简单说,route 是“信息载体”,router 是“操作工具”,一个负责存数据,一个负责执行跳转~

route 里都包含哪些关键信息?

知道了route是信息对象,那它里面到底藏着啥?咱拆成几个核心属性来讲,每个属性在项目里都有实用场景:

path:当前路径的字符串

比如你访问 http://xxx/user/123this.$route.path 拿到的就是 '/user/123',主要用来判断当前页面属于哪个路由分支,比如导航栏高亮当前页时会用到。

params:动态路由参数

如果路由配置是 path: '/user/:id',那么访问 /user/123 时,this.$route.params.id '123',它属于路径的一部分,适合传“必须和路径绑定”的参数(比如用户ID、商品ID),但要注意:如果路由没定义 :id 这种动态段,直接用 params 传参,页面刷新后参数会丢失!

query:查询参数

对应URL里 后面的部分,http://xxx/user?tab=infothis.$route.query.tab 'info',它的特点是刷新页面不会丢,适合传“可选、临时”的参数(比如搜索关键词、分页页码)。

meta:路由元信息

这是个超级实用的属性!你可以在路由配置里给每个路由加 meta,存一些自定义数据,比如权限要求、页面标题、是否缓存组件,举个路由配置的例子:

```js const routes = [ { path: '/admin', component: Admin, meta: { requiresAuth: true, // 需要登录权限 title: '后台管理' // 页面标题 } } ] ```

之后在导航守卫或组件里,通过 this.$route.meta.requiresAuth 就能拿到这些配置,用来做权限判断、设置页面标题超方便~

matched:匹配的路由记录数组

当用嵌套路由时,matched 会存所有“从父到子”的路由记录,比如父路由是 /home,子路由是 /home/articlethis.$route.matched 是一个长度为2的数组,第0项是父路由信息,第1项是子路由信息,这个属性常用于做面包屑导航(首页 > 文章列表”)。

hash:URL的哈希值(可选)

如果项目用的是 hash 模式(URL里有 ),this.$route.hash 能拿到 后面的内容(#section1),不过现在大多项目用 history 模式,这个属性用得少,但了解下没坏处~

总结下,route里的这些属性就像“路由的身份证+随身行李”,每个属性在不同场景下都能帮我们精准控制页面逻辑~

怎么在项目里获取 route 信息?

不同场景下获取route的方式不一样,咱分Vue2、Vue3,还有路由守卫这些场景一个个说:

Vue2 组件内:this.$route

只要组件在路由系统里(被 <router-view> 渲染),就能通过 this.$route 拿到当前路由信息,比如在组件的生命周期钩子、方法里:

```js export default { mounted() { // 获取路径 console.log(this.$route.path); // 获取动态参数 console.log(this.$route.params.id); // 获取查询参数 console.log(this.$route.query.search); }, methods: { handleClick() { // 也能在方法里用 const userId = this.$route.params.id; this.fetchUserInfo(userId); } } } ```

Vue3 组合式API:useRoute()

Vue3里要先导入 useRoute,再调用拿到route对象:

```js import { defineComponent, onMounted } from 'vue'; import { useRoute } from 'vue-router';

export default defineComponent({
setup() {
const route = useRoute();
onMounted(() => {
console.log(route.path);
console.log(route.params.id);
});
return {};
}
});

<p>注意哦,<code>useRoute</code> 必须在 <code>setup</code> 里用,而且组件得在路由系统中,不然会报错~  
### 3. 路由守卫里:to / from 参数  
<p>不管是全局守卫(<code>router.beforeEach</code>)、路由独享守卫(<code>beforeEnter</code>),还是组件内守卫(<code>beforeRouteEnter</code> 这些),参数里的 <code>to</code> 和 <code>from</code> 都是route对象,举个全局守卫的例子:</p>  
```js  
const router = createRouter({ ... });  
router.beforeEach((to, from, next) => {  
  // to 是目标路由的route对象,from 是当前路由的route对象  
  if (to.meta.requiresAuth && !isLogin()) {  
    next('/login'); // 没登录就跳登录页  
  } else {  
    next(); // 放行  
  }  
});  

组件内守卫比如 beforeRouteEnter(组件创建前触发),这时候组件实例还没生成,所以不能用 this.$route,但可以通过 to 参数拿到信息:

```js export default { beforeRouteEnter(to, from, next) { // 这里拿to.params.id const productId = to.params.id; // 可以提前发请求,等组件创建后把数据传过去 next(vm => { vm.productId = productId; vm.fetchProductDetail(productId); }); } } ```

不同场景对应不同的获取方式,组件内用this.$route/useRoute,守卫里用to/from”就好~

route 的参数(params/query)咋处理?

params和query是route里最常用的参数,但很多同学刚上手容易搞混或者踩坑,咱从“设置、获取、避坑”三个角度讲:

params vs query:核心区别

对比项 params query
路径关联 属于路径的一部分(如 /user/:id) 属于URL的查询部分(如 ?tab=info)
刷新保留 路由没定义动态段时,刷新丢失;定义了则保留 刷新后仍存在
传参方式 需配合路由name或路径动态段 可直接在路径后拼接,或用对象传参

怎么设置 params/query?

通常用 router.push 来跳转并传参,两种方式:

  • 命名路由 + params:适合传动态路径参数(需路由配置动态段) ```js // 路由配置:{ name: 'user', path: '/user/:id' } this.$router.push({ name: 'user', params: { id: 123 } }); // 跳转后的URL:/user/123 ```
  • 路径 + query:适合传查询参数 ```js this.$router.push({ path: '/home', query: { tab: 'news' } }); // 跳转后的URL:/home?tab=news ```
  • 混合传参:也可以同时传params和query(但params要配合name) ```js this.$router.push({ name: 'product', params: { id: 456 }, query: { sort: 'price' } }); // URL:/product/456?sort=price ```

怎么获取 params/query?

前面讲过,直接从 this.$route 里拿:

```js // 获取params const userId = this.$route.params.id; // 获取query const activeTab = this.$route.query.tab; ```

避坑指南

▪️ params刷新丢失:如果路由没配 :id 这种动态段,只靠 name + params 传参,刷新页面后params会变成空对象!解决方法:路由配置里必须定义动态段(如 path: '/user/:id'),让params和URL绑定。

▪️ 参数变化时组件不更新:比如从 /user/1 跳到 /user/2,因为组件会复用,所以生命周期钩子(如mounted)不会重新执行,这时候要监听route变化:

```js // Vue2 用watch watch: { '$route'(to, from) { // to是新路由,from是旧路由 this.fetchUserInfo(to.params.id); } }

// Vue3 用watchEffect或watch
import { watch } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();
watch(
() => route.params.id,
(newId) => {
fetchUserInfo(newId);
}
);

<p>或者用组件内守卫 <code>beforeRouteUpdate</code>:</p>  
```js  
export default {  
  beforeRouteUpdate(to, from, next) {  
    this.fetchUserInfo(to.params.id);  
    next();  
  }  
}  

把params和query的逻辑理清楚,页面传参、数据加载就稳多了~

route 在导航守卫里咋用?

导航守卫是控制路由跳转的“关卡”,而route对象(to/from)是守卫里的核心数据,咱分三类守卫讲route的作用:

全局守卫:router.beforeEach

全局守卫会拦截所有路由跳转,to 是目标路由的route对象,from 是当前路由的route对象,最经典的用法是权限控制

```js router.beforeEach((to, from, next) => { // 判断目标路由是否需要登录 if (to.meta.requiresAuth) { // 检查是否登录(假设isLogin()是自定义方法) if (isLogin()) { next(); // 已登录,放行 } else { next('/login'); // 没登录,跳登录页 } } else { next(); // 不需要权限,直接放行 } }); ```

还能用来做设置:如果路由meta里配了title,全局守卫里动态设置文档标题:

```js router.beforeEach((to, from, next) => { if (to.meta.title) { document.title = to.meta.title; } next(); }); ```

路由独享守卫:beforeEnter

写在单个路由配置里,只拦截当前路由的跳转,比如某个路由需要更细粒度的权限判断:

```js const routes = [ { path: '/order', component: Order, beforeEnter: (to, from, next) => { // 比如判断是否有订单权限 if (hasOrderPermission()) { next(); } else { next('/no-permission'); } } } ] ```

这里的to和from同样是route对象,能拿到目标路由和当前路由的所有信息~

组件内守卫:beforeRouteEnter / beforeRouteUpdate / beforeRouteLeave

这三个守卫写在组件内部,针对性更强:

  • beforeRouteEnter:组件创建前触发,this 还没生成,所以用 to 拿目标路由信息,适合提前发请求: ```js export default { beforeRouteEnter(to, from, next) { // 拿到商品ID const productId = to.params.id; // 发请求拿详情 fetchProductDetail(productId).then(data => { // 组件创建后把数据传过去 next(vm => { vm.productData = data; }); }); } } ```
  • beforeRouteUpdate:路由参数变化时触发(组件复用场景),能拿到新的 to 和旧的 from,适合参数变化后更新数据: ```js export default { beforeRouteUpdate(to, from, next) { // 比如用户从 /user/1 跳到 /user/2 this.fetchUserInfo(to.params.id); next(); } } ```
  • beforeRouteLeave:离开当前路由时触发,常用于拦截未保存的表单: ```js export default { beforeRouteLeave(to, from, next) { if (this.formDirty) { // 假设formDirty标记表单是否修改 if (confirm('表单还没保存,确定离开吗?')) { next(); // 确认离开 } else { next(false); // 取消离开,留在当前页 } } else { next(); // 表单没修改,直接离开 } } } ```

导航守卫+route对象,相当于给路由跳转加了“智能管家”——能控制权限、预加载数据、拦截误操作,让页面跳转更安全流畅~

route 处理嵌套路由时有啥技巧?

嵌套路由(比如父路由里套子路由)是项目里很常见的结构,route的 matched 属性在这时候特别好用,咱用“面包屑导航”这个经典场景举例:

嵌套路由的配置示例

const routes = [  
  {  
    path: '/home',  
    component: Home,  
    meta: { title: '首页' },  
    children: [  
      {  
        path: 'article',  
        component: Article,  
        meta: { title: '文章列表' }  
      },  
      {  
        path: 'article/:id',  
        component:

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门