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

一、Vue Router Object 是个啥?

terry 23小时前 阅读数 20 #Vue

p>做Vue项目开发时,路由功能几乎是刚需,但很多同学刚接触Vue Router,对「Vue Router Object」总是一知半解:它到底是什么?怎么在组件里调用?动态路由、权限控制这些场景怎么靠它实现?今天咱们就把这个Vue路由的核心对象拆开讲,从基础概念到实战避坑,一次性搞懂!


你可以把它理解成整个Vue项目的“路由大管家”——所有路由规则、页面跳转逻辑、当前路由状态,都由这个对象统一管理。

先看创建它的代码:

// router.js 文件
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: () => import('./views/About.vue') }
]
// 这里创建的 router Vue Router Object!
const router = createRouter({
  history: createWebHistory(), // 路由模式(history/hash)
  routes // 路由规则数组
})
export default router

这个router对象一旦创建,就会成为单例(整个项目就这一个),负责:

  • 存储所有路由规则(比如对应Home组件,/about对应About组件);
  • 提供「跳转页面」「前进后退」这些方法(像router.pushrouter.go);
  • 记录当前路由状态(比如现在在哪个页面、URL里的参数是啥,对应router.currentRoute);
  • 处理导航守卫(比如页面跳转前判断用户是否登录,对应router.beforeEach)。

简单说:它是Vue Router的“心脏”,路由功能的方方面面都得靠它运转

Vue Router Object 有哪些核心“技能”?

要用好这个大管家,得先摸清它的核心属性和方法,可以分成“状态属性”“操作方法”两类。

核心属性:看状态

  • router.currentRoute:当前路由的详细信息(响应式的!),比如你在/user/123?tab=info页面,它会包含:

    {
      path: '/user/123', 
      params: { id: '123' }, 
      query: { tab: 'info' }, 
      name: 'user', // 路由命名的话才有
      meta: { ... } // 路由元信息
    }

    在组件里,用useRoute()(组合式API)或this.$route(选项式API)能拿到这个对象,而且它会自动响应式更新(参数变了、路径变了,它也会变)。

  • router.options:创建路由时的“原始配置”,比如你初始化时传的routes数组、history模式,都存在这里,一般调试或动态路由时会用到。

核心方法:做操作

路由跳转、动态加路由、前进后退…全靠这些方法:

  • router.push():最常用的“跳转到新页面”,它会往浏览器历史栈里新增一条记录(点返回能回到上一页),用法灵活:

    // 方式1:直接写路径字符串
    router.push('/user/123')  
    // 方式2:命名路由 + 动态参数(推荐!解耦路径和参数)
    router.push({ name: 'user', params: { id: 123 } })  
    // 方式3:带查询参数(?后面的部分)
    router.push({ path: '/user', query: { tab: 'profile' } })  
  • router.replace():和push类似,但它会替换当前历史记录(点返回不会回到当前页,而是更前一页),比如支付成功后跳结果页,用replace避免用户回退又到支付页。

  • router.go(n):控制历史记录的前进后退,n是数字,比如router.go(1)前进一页,router.go(-1)后退一页,和浏览器的「前进/后退」按钮逻辑一样。

  • router.back() / router.forward()go(-1)go(1)的快捷写法,更语义化。

  • router.addRoute() / router.removeRoute():动态添加/删除路由规则。权限管理、异步路由的核心!比如后台系统,管理员登录后才加载/admin路由:

    // 登录后,给管理员加专属路由
    if (user.role === 'admin') {
      router.addRoute({
        path: '/admin',
        component: () => import('./views/Admin.vue')
      })
    }

组件里怎么“喊”这个大管家?

路由对象是单例,但在不同场景(组件内、组件外)访问方式不一样。

组件内部:用钩子函数

Vue 3的组合式API里,用useRouter()useRoute()

<template>
  <button @click="goToAbout">去关于页</button>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter() // 拿到路由对象
function goToAbout() {
  router.push('/about') // 跳转
}
</script>

Vue 2的选项式API,或者Vue 3里用选项式写法,用this.$routerthis.$route(前提是Vue实例里注入了路由):

export default {
  methods: {
    goToAbout() {
      this.$router.push('/about')
    }
  }
}

注意:想拿“当前路由信息”(比如参数、查询参数),用useRoute()this.$route;想“操作路由”(跳转、加路由),用useRouter()this.$router

组件外部:直接导入实例

如果在Vuex仓库工具函数JS文件里操作路由,直接导入创建好的router实例就行:

// router.js(创建路由的文件)
export const router = createRouter({ ... }) // 注意要导出
// utils/auth.js(工具文件)
import { router } from '../router.js'
// 登录成功后跳转
function loginSuccess() {
  router.push('/dashboard')
}

实战:用Vue Router Object 搞动态路由、权限控制

很多复杂场景(比如权限路由、多租户系统),核心就是动态增删路由 + 导航守卫

场景1:根据用户权限加载路由(动态路由)

后台系统里,普通用户看不到/admin页面,管理员登录后才加载这个路由,步骤:

  1. 先在路由规则里写个“占位符”(可选,也可以完全动态加);
  2. 登录成功后,用router.addRoute()加管理员路由;
  3. 用导航守卫(router.beforeEach)拦截未授权访问。

代码示例:

// router.js 初始化时,先不加/admin路由
const routes = [
  { path: '/login', component: Login },
  { path: '/', component: Home, meta: { requiresAuth: true } }
]
const router = createRouter({ ... })
// 全局前置守卫:跳转前检查权限
router.beforeEach((to, from, next) => {
  // 如果目标页面需要登录,且用户没登录,跳登录页
  if (to.meta.requiresAuth && !isLoggedIn()) {
    next({ name: 'login' })
  } else {
    next() // 放行
  }
})
// 登录逻辑(比如在Login组件里)
function handleLogin() {
  // 假设登录后拿到用户角色
  const user = loginApi() 
  if (user.role === 'admin') {
    // 动态添加管理员路由
    router.addRoute({
      path: '/admin',
      component: () => import('./views/Admin.vue'),
      meta: { requiresAuth: true }
    })
  }
  // 跳转到首页
  router.push('/')
}

场景2:路由元信息(meta)控制页面行为

路由元信息是给路由“贴标签”的,比如标记“是否需要登录”“页面标题”“过渡动画”。

配置路由时加meta

{
  path: '/profile',
  component: Profile,
  meta: { 
    requiresAuth: true,  '个人中心',
    transition: 'fade' // 过渡动画名称
  }
}

然后在导航守卫里用to.meta做逻辑:

router.beforeEach((to, from, next) => {
  // 设置页面标题
  document.title = to.meta.title || '默认标题'
  next()
})

或者在组件里根据meta做过渡动画:

<router-view v-slot="{ Component, route }">
  <Transition :name="route.meta.transition || 'slide'">
    <component :is="Component" />
  </Transition>
</router-view>

避坑指南:这些问题90%的人都踩过

路由开发时,有些“玄学”问题其实是对路由对象理解不到位导致的,这里列几个高频坑:

坑1:路由跳转后,组件没更新

比如从/user/1跳到/user/2,URL变了但页面数据没刷新。原因是Vue复用了相同组件(路径结构一样,只是参数变了),组件的生命周期没触发。

解决方法:

  • 监听路由变化:在组件里用watch监听$route(或useRoute())的变化,参数变了就重新请求数据。
    // 组合式API
    import { useRoute, watch } from 'vue-router'
    const route = useRoute()
    watch(route, (newRoute) => {
      // newRoute.params.id 变化了,重新请求数据
      fetchUser(newRoute.params.id)
    })
  • 给组件加key:让Vue认为是不同组件,强制销毁重建。
    <template>
      <UserComponent :key="$route.params.id" />
    </template>

坑2:动态加路由重复了

多次调用router.addRoute()会导致同一路由被重复添加,页面可能出问题。解决方法是先检查是否已存在

if (!router.hasRoute('admin')) { // hasRoute 检查路由是否存在(按name判断)
  router.addRoute({ name: 'admin', path: '/admin', component: Admin })
}

坑3:history模式下刷新页面404

createWebHistory()(history模式)时,直接刷新页面,后端如果没配置,会返回404。原因是前端路由走的是HTML5 History API,后端不认识前端的路由路径

解决:让后端把所有前端路由的请求,都转发到index.html,比如Nginx配置:

location / {
  try_files $uri $uri/ /index.html;
}

坑4:导航守卫里next()用错了

导航守卫(比如beforeEach)里的next()是控制导航是否继续的函数,必须确保只调用一次!比如异步逻辑里没处理好,就会报错。

错误示例(多次调用next):

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    next({ name: 'login' }) // 这里调了next
  }
  next() // 又调了next,重复调用会报错!
})

正确写法(确保只调一次):

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isLoggedIn()) {
    next({ name: 'login' })
  } else {
    next() // 只在else里调
  }
})

进阶:路由对象还能玩出啥花样?

除了基础功能,结合Vue生态,路由对象能搞很多高阶玩法:

路由过渡动画的精细化控制

不同页面用不同过渡效果,靠route.meta.transition动态切换:

<router-view v-slot="{ Component, route }">
  <Transition :name="route.meta.transition">
    <component :is="Component" />
  </Transition>
</router-view>

然后在路由配置里指定:

{
  path: '/home',
  component: Home,
  meta: { transition: 'slide-left' }
},
{
  path: '/about',
  component: About,
  meta: { transition: 'slide-right' }
}

路由懒加载 + 进度条

结合import()懒加载和NProgress进度条,路由跳转时显示加载状态:

// 全局路由守卫里加进度条逻辑
import NProgress from 'nprogress'
router.beforeEach((to, from, next) => {
  NProgress.start() // 开始加载
  next()
})
router.afterEach(() => {
  NProgress.done() // 加载完成
})
// 路由规则里用懒加载
{
  path: '/about',
  component: () => {
    NProgress.set(0.5) // 加载到一半时设进度
    return import('./views/About.vue')
  }
}

多标签页(类似浏览器标签)

模拟多标签页功能,用router.push配合keep-alive和标签数组,记录用户打开的页面:

// 存储打开的标签页
const visitedTabs = ref([])
function openTab(path) {
  if (!visitedTabs.value.includes(path)) {
    visitedTabs.value.push(path)
  }
  router.push(path)
}
// 模板里循环渲染标签
<template>
  <div v-for="path in visitedTabs" :key="path">
    <button @click="router.push(path)">{{ path }}</button>
  </div>
  <router-view v-slot="{ Component }">
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </router-view>
</template>

掌握Vue Router Object 等于掌控路由命脉

从基础的“是什么”,到核心的“怎么用”,再到实战的“怎么玩出花”,Vue Router Object 贯穿了路由开发的全流程,理解它的属性、方法,结合导航守卫、动态路由、元信息这些工具,不管是简单的页面跳转,还是复杂的权限管理、多端适配,都能游刃有余。

最后再强调个心法:路由对象是“管理者”,它的一切设计都是为了让路由逻辑更集中、更可控,遇到路由问题时,先想“路由对象能提供什么方法/属性”,很多问题自然就有了方向~

版权声明

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

发表评论:

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

热门