一、前言:为什么需要 Vue Router?

在传统多页面应用中,页面跳转依赖后端路由(通过 URL 请求不同 HTML 文件),存在页面刷新、加载缓慢、用户体验差等问题。而 Vue 作为单页面应用(SPA)框架,需要一套前端路由方案来实现 “无刷新页面切换”——Vue Router 应运而生。

Vue Router 是 Vue 官方配套的路由插件,核心作用是:

  1. 建立 URL 与组件的映射关系
  2. 实现无刷新的页面跳转(通过操作 History API 或 Hash)
  3. 支持路由参数、嵌套路由、路由守卫等高级功能
  4. 与 Vue 生态深度集成,实现组件化的路由管理

本文将从安装配置→核心用法→进阶技巧→实战案例,带你全面掌握 Vue Router(基于 Vue 3 + Vue Router 4,兼容 Vue 2 迁移指南)。

二、快速上手:Vue Router 安装与基础配置

1. 安装依赖

根据项目环境选择安装方式:

# Vue 3 + Vue Router 4(推荐)

npm install vue-router@4

# 或 yarn

yarn add vue-router@4

# Vue 2 + Vue Router 3(兼容旧项目)

npm install vue-router@3

2. 基础配置步骤(Vue 3 示例)
步骤 1:创建路由实例

src/router/index.js中配置路由规则:

// 1. 导入依赖

import { createRouter, createWebHistory } from 'vue-router'

// 导入需要路由的组件

import Home from '@/views/Home.vue'

import About from '@/views/About.vue'

import NotFound from '@/views/NotFound.vue'

// 2. 定义路由规则(path→component映射)

const routes = [

  {

    path: '/', // 根路径

    name: 'Home', // 路由名称(可选,用于编程式导航)

    component: Home // 对应组件

  },

  {

    path: '/about',

    name: 'About',

    component: About

  },

  {

    path: '/:pathMatch(.*)*', // 404路由(匹配所有未定义路径)

    name: 'NotFound',

    component: NotFound

  }

]

// 3. 创建路由实例

const router = createRouter({

  history: createWebHistory(import.meta.env.BASE_URL), // HTML5 History模式(无#)

  // history: createWebHashHistory(), // Hash模式(URL带#,兼容性更好)

  routes // 注入路由规则

})

// 4. 导出路由实例

export default router

步骤 2:在 Vue 中注入路由

src/main.js中引入并使用路由:

import { createApp } from 'vue'

import App from './App.vue'

import router from './router' // 导入路由实例

const app = createApp(App)

app.use(router) // 注入路由

app.mount('#app')

步骤 3:使用路由导航与视图

App.vue中添加路由链接和路由出口:

  ">

    链接(替代a标签,无刷新跳转) -->

     首页      about">关于我们-link>

    >

    

    出口:匹配的组件将渲染在这里 -->

    <router-view />

  </div>

激活的路由链接样式(默认类名:router-link-active) */

.router-link-active {

  color: red;

  font-weight: bold;

}

</style>

三、核心用法:掌握路由的关键特性

1. 路由参数(动态路由)

场景:需要根据 URL 参数渲染不同内容(如详情页)。

配置动态路由:

// router/index.js

const routes = [

  {

    path: '/user/:id', // :id为动态参数(可多个:/user/:id/:name)

    name: 'User',

    component: () => import('@/views/User.vue') // 懒加载组件(优化性能)

  }

]

在组件中获取参数:

<!-- User.vue -->

<template>

  >用户ID:{{ $route.params.id }}

</template>

 setup>

// 方式1:通过$route(简易)

import { useRoute } from 'vue-router'

const route = useRoute()

console.log(route.params.id) // 打印URL中的id参数

// 方式2:解构参数(推荐,更清晰)

const { id } = route.params

>

2. 编程式导航(替代 router-link)

场景:需要通过按钮点击等逻辑触发跳转。

// 组件中使用

import { useRouter } from 'vue-router'

const router = useRouter()

// 1. 跳转到指定路径

const goToHome = () => {

  router.push('/')

}

// 2. 通过路由名称跳转(需配置name)

const goToAbout = () => {

  router.push({ name: 'About' })

}

// 3. 带参数跳转

const goToUser = (userId) => {

  router.push({

    name: 'User',

    params: { id: userId } // 动态参数

  })

  // 或 query参数(URL拼接:/user?id=123)

  // router.push({ path: '/user', query: { id: userId } })

}

// 4. 后退/前进

const goBack = () => {

  router.go(-1) // 后退1步

  // router.forward() // 前进一步

}

3. 嵌套路由(多级路由)

场景:页面存在多级导航(如首页→商品列表→商品详情)。

配置嵌套路由:

// router/index.js

const routes = [

  {

    path: '/product',

    name: 'Product',

    component: () => import('@/views/Product.vue'),

    children: [ // 子路由

      {

        path: 'list', // 子路径(URL:/product/list)

        name: 'ProductList',

        component: () => import('@/views/ProductList.vue')

      },

      {

        path: 'detail/:id', // 子路由带参数(URL:/product/detail/1)

        name: 'ProductDetail',

        component: () => import('@/views/ProductDetail.vue')

      }

    ]

  }

]

父组件中添加子路由出口:

<template>

  <div>

    2>商品模块2>

    -link to="/product/list">商品列表

     在这里 -->

  >

4. 路由守卫(权限控制核心)

路由守卫用于拦截路由跳转,实现权限校验、页面拦截等功能,分为 3 类:

(1)全局守卫(影响所有路由)

// router/index.js

// 路由跳转前触发(可拦截)

router.beforeEach((to, from, next) => {

  // to:即将进入的路由

  // from:即将离开的路由

  // next:放行函数(next()放行,next('/login')跳转,next(false)取消)

  

  // 示例:未登录拦截(除了登录页都需要登录)

  const isLogin = localStorage.getItem('token')

  if (to.path !== '/login' && !isLogin) {

    next('/login') // 未登录跳转到登录页

  } else {

    next() // 已登录放行

  }

})

// 路由跳转后触发(不可拦截)

router.afterEach((to, from) => {

  // 示例:修改页面标题

  document.title = to.meta.title || 'Vue Router示例'

})

(2)路由独享守卫(只影响当前路由)

// router/index.js

const routes = [

  {

    path: '/admin',

    name: 'Admin',

    component: () => import('@/views/Admin.vue'),

    meta: { requiresAuth: true }, // 自定义元信息(标记需要权限)

    // 路由独享守卫

    beforeEnter: (to, from, next) => {

      const isAdmin = localStorage.getItem('isAdmin')

      if (isAdmin) {

        next()

      } else {

        next('/403') // 无权限跳转到403页面

      }

    }

  }

]

(3)组件内守卫(影响当前组件)

 -->

import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router'

// 进入组件前触发

onBeforeRouteEnter((to, from, next) => {

  // 注意:此时组件实例未创建,无法访问this

  next(vm => {

    // vm为组件实例,可访问vm.$data等

    console.log('进入组件:', vm)

  })

})

// 离开组件前触发

onBeforeRouteLeave((to, from, next) => {

  // 示例:确认是否离开

  if (confirm('确定要离开吗?未保存的数据将丢失')) {

    next()

  } else {

    next(false)

  }

})

四、进阶优化:提升路由使用体验

1. 路由懒加载(优化首屏加载速度)

默认情况下,所有组件会在首屏一次性加载,导致打包体积过大。路由懒加载通过 “按需加载” 组件,减少首屏加载时间:

// 替换直接import为动态import

const routes = [

  {

    path: '/about',

    name: 'About',

    // 懒加载写法(推荐)

    component: () => import('@/views/About.vue')

  }

]

// 可选:给懒加载组件分组(打包时合并为一个chunk)

component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue')

2. 路由元信息(meta)

用于存储路由的额外信息(如标题、权限要求),在守卫中使用:

const routes = [

  {

    path: '/about',

    name: 'About',

    component: () => import('@/views/About.vue'),

    meta: {

      title: '关于我们', // 页面标题

      requiresAuth: false // 是否需要登录

    }

  }

]

// 在全局守卫中使用

router.beforeEach((to, from, next) => {

  if (to.meta.title) {

    document.title = to.meta.title

  }

  next()

})

3. 滚动行为(页面跳转后滚动位置)

控制路由跳转后页面的滚动位置(如返回上一页保留滚动位置):

const router = createRouter({

  history: createWebHistory(),

  routes,

  // 滚动行为配置

  scrollBehavior(to, from, savedPosition) {

    if (savedPosition) {

      // 后退/前进时恢复滚动位置

      return savedPosition

    } else {

      // 默认滚动到顶部

      return { top: 0 }

    }

  }

})

五、实战案例:实现登录权限控制

结合前面的知识点,实现一个完整的 “登录→权限校验→跳转” 流程:

  1. 登录页面(Login.vue):输入账号密码,登录成功后存储 token 到本地存储。
  2. 路由守卫:未登录时拦截需要权限的路由,跳转到登录页。
  3. 首页(Home.vue):登录后可访问,显示退出登录按钮。
关键代码:

// Login.vue 登录逻辑

const login = () => {

  // 模拟接口请求

  setTimeout(() => {

    localStorage.setItem('token', 'fake-token-123') // 存储token

    router.push('/') // 登录成功跳转到首页

  }, 1000)

}

// 首页退出登录

const logout = () => {

  localStorage.removeItem('token') // 清除token

  router.push('/login') // 跳转到登录页

}

// 路由守卫(权限控制)

router.beforeEach((to, from, next) => {

  const isLogin = localStorage.getItem('token')

  // 需要权限的路由(meta.requiresAuth为true)

  const requiresAuth = to.meta.requiresAuth

  if (requiresAuth && !isLogin) {

    next('/login')

  } else {

    next()

  }

})

// 路由配置

const routes = [

  { path: '/login', component: () => import('@/views/Login.vue') },

  {

    path: '/',

    component: () => import('@/views/Home.vue'),

    meta: { requiresAuth: true } // 需要登录

  }

]

六、常见问题与避坑指南

  1. 路由跳转后页面不刷新?

原因:路由参数变化但组件未重新渲染(如/user/1/user/2)。

解决:监听$route变化,或使用key强制刷新组件:

 :key="$route.fullPath" />

  1. History 模式部署后刷新 404?

原因:History 模式依赖 HTML5 History API,刷新时服务器会请求该 URL,导致 404。

解决:配置服务器路由重定向(如 Nginx、Apache),将所有请求指向index.html

  1. 路由守卫中 next () 调用时机?

必须调用next(),否则路由会卡住;避免多次调用next()(如在条件判断中遗漏else)。

  1. 懒加载组件报错?

检查路径是否正确(使用@别名时确保配置正确),Vue Router 4 需配合 Vue 3 使用。

七、总结

Vue Router 是 Vue 生态的核心插件,掌握其基础配置、动态路由、嵌套路由、路由守卫四大核心知识点,就能满足绝大多数 SPA 项目的路由需求。实际开发中,结合懒加载、滚动行为、元信息等优化技巧,可进一步提升项目性能和用户体验。

如果需要更复杂的场景(如路由缓存、多路由出口、Vuex/Pinia 结合路由),或 Vue 2 到 Vue 3 的迁移细节,欢迎在评论区交流!

附:参考资料

(注:文档部分内容可能由 AI 生成)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐