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

一、Vue Router 4 基础认知,和前代有啥不同?

terry 3小时前 阅读数 13 #Vue

p>想系统掌握 Vue Router 4,得先理清它在 Vue3 生态里的角色和学习逻辑,简单说,路由是单页应用(SPA)实现“多页面感”的核心工具,Vue Router 4 作为 Vue3 官方路由库,和 Vue3 组合式 API、响应式系统深度绑定,用法和 Vue Router 3(对应 Vue2)差异不小,下面通过“基础认知、核心功能、进阶能力、实战场景、避坑学习”五大模块,用问答形式拆解关键知识点,帮你把技术点串成可落地的技能。

问题1:Vue Router 4 是做什么的?和 Vue Router 3 核心差异在哪?
Vue Router 4 是 Vue3 生态中负责管理页面跳转规则、组件与路径映射、导航逻辑的工具库,和 Vue Router 3 相比,核心差异体现在这几点:

  • 初始化方式:Vue3 用 createApp 构建应用,Vue Router 4 改用 createRouter + createWebHistory/createWebHashHistory 配置路由,告别 Vue2 时代的 new Router()
  • 组合式 API 支持:新增 useRouteruseRoute 等组合式函数,在 setup 语法糖中能更简洁地操作路由(比如获取参数、编程式导航)。
  • 性能优化:支持 Tree-shaking,打包时自动剔除未使用的路由功能,减少项目体积。
  • 路由匹配逻辑:动态路由、嵌套路由的配置细节更严谨(比如嵌套路由 children 需严格对应父组件的 <router-view> 结构)。

问题2:项目里怎么安装 Vue Router 4?基本配置步骤是啥?
安装很简单,用包管理器执行命令:

npm install vue-router@4  # 或 yarn add vue-router@4

配置分三步(以 Vue3 + Vite 项目为例):

  1. 创建路由实例:在 src/router/index.js 中定义路由规则和模式:
    import { createRouter, createWebHistory } from 'vue-router'
    // 导入组件(懒加载用动态 import)
    import HomeView from '../views/HomeView.vue'

const router = createRouter({ history: createWebHistory(), // History 模式(URL 无 #,需后端配置);Hash 模式用 createWebHashHistory routes: [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: () => import('../views/AboutView.vue') // 懒加载:访问时再加载组件 } ] })

export default router


2. **注入 Vue 应用**:在 `main.js` 中把路由实例挂载到 Vue 应用上:  
```js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router) // 注入路由功能
app.mount('#app')
  1. 渲染路由组件:在 App.vue 中用 <router-view> 显示匹配组件,<router-link> 做导航:
    <template>
    <div class="app-nav">
     <router-link to="/">首页</router-link>
     <router-link to="/about">lt;/router-link>
    </div>
    <router-view></router-view> <!-- 匹配的组件会渲染到这里 -->
    </template>

核心功能实操:动态路由、嵌套路由咋玩?

问题3:动态路由(带参数的路由)怎么配置和使用?
动态路由用于路径含变量的场景(比如用户 ID、文章 ID),配置时在 path 中加 :参数名,示例:

routes: [
  {
    path: '/user/:id', // :id 是动态参数
    name: 'User',
    component: () => import('../views/UserView.vue')
  }
]

组件内获取参数分两种方式:

  • 组合式 API:用 useRoute() 获取当前路由对象,通过 route.params.id 拿到参数:
    import { useRoute, watch } from 'vue-router'
    export default {
    setup() {
      const route = useRoute()
      // 监听参数变化(因为动态路由复用组件时,生命周期不触发,需手动监听)
      watch(() => route.params.id, (newId) => {
        console.log('用户 ID 变化:', newId)
        // 这里可执行请求新用户数据等逻辑
      })
    }
    }
  • 选项式 API:通过 this.$route.params.id 获取参数,同样需注意组件复用时的参数监听(用 watch: { '$route.params.id'() {} })。

问题4:嵌套路由怎么设计?适合什么场景?
嵌套路由是“父路由包含子路由”的结构,典型场景是后台管理系统/layout 页面包含侧边栏、顶栏,中间 <router-view> 显示子页面如 /layout/dashboard)。

配置时用 children 数组:

routes: [
  {
    path: '/layout',
    component: LayoutView, // 父组件,需包含 <router-view> 显示子组件
    children: [
      {
        path: 'dashboard', // 注意:path 不加 /,自动拼接为 /layout/dashboard
        name: 'Dashboard',
        component: DashboardView
      },
      {
        path: 'settings',
        name: 'Settings',
        component: SettingsView
      }
    ]
  }
]

父组件 LayoutView 的模板需包含 <router-view>

<template>
  <div class="layout-container">
    <aside>侧边导航栏</aside>
    <main>
      <router-view></router-view> <!-- 子路由组件渲染到这里 -->
    </main>
  </div>
</template>

这种设计让“父布局逻辑”和“子页面内容”解耦,代码更模块化。

问题5:编程式导航(不用 <router-link> 跳转)怎么做?
场景比如“点击按钮跳转”“登录成功后跳转到首页”,用 useRouter() 拿到路由实例,调用 push/replace/go 等方法:

  • 组合式 API 写法

    import { useRouter } from 'vue-router'
    export default {
    setup() {
      const router = useRouter()
      const goToAbout = () => {
        // 方式1:直接传路径
        router.push('/about') 
        // 方式2:传路由对象(name 对应路由配置的 name)
        router.push({ name: 'about' }) 
        // replace:替换当前历史记录(返回时跳过当前页)
        router.replace('/about')
        // go(-1):返回上一页,类似 history.back()
        router.go(-1)
      }
      return { goToAbout }
    }
    }
  • 选项式 API 写法:用 this.$router.push(...),用法和上面一致。

push/replace 可传查询参数(如 router.push({ path: '/search', query: { keyword: 'vue' } })),组件内通过 route.query.keyword 获取参数。

进阶能力:路由守卫、元信息、懒加载有啥用?

问题6:路由守卫是做什么的?全局守卫、组件内守卫怎么用?
路由守卫是“路由跳转前后的钩子函数”,用于权限验证、加载进度条、数据预加载等场景,分三类:

  • 全局守卫:作用于所有路由跳转,在路由实例上配置:

    • router.beforeEach((to, from) => { ... }):跳转前触发,返回值控制是否允许跳转(返回 true/undefined 允许;返回 false/路径字符串则中断并跳转)。
      示例:权限验证(未登录则跳登录页):
      import { useUserStore } from '@/stores/user' // 假设用 Pinia 存用户状态

    router.beforeEach((to) => { const userStore = useUserStore() if (to.meta.requiresAuth && !userStore.isLogin) { return '/login' // 无权限则跳登录页 } })

    
    - `router.afterEach((to, from) => { ... })`:跳转完成后触发,适合“修改页面标题”“关闭加载动画”等操作。  
  • 路由独享守卫:在单个路由配置中写 beforeEnter

    {
    path: '/admin',
    component: AdminView,
    beforeEnter: (to, from) => {
      if (!isAuthenticated()) return '/login' // 仅该路由触发此守卫
    }
    }
  • 组件内守卫:在组件的 setup 中用组合式 API 钩子(选项式 API 用 beforeRouteUpdate/beforeRouteLeave):

    • onBeforeRouteUpdate:路由参数变化时触发(如 /user/1/user/2,组件复用场景)。
    • onBeforeRouteLeave:离开当前路由时触发(如“表单未保存时阻止跳转”)。

示例:离开页面时确认是否保存表单:

import { onBeforeRouteLeave } from 'vue-router'
export default {
  setup() {
    onBeforeRouteLeave((to, from) => {
      if (form.dirty) { // 假设 form 有“是否修改”标记
        return window.confirm('有未保存内容,确定离开?')
      }
    })
  }
}

问题7:路由元信息(meta)怎么配置和使用?
meta 是给路由加“额外信息”的字段,是否需要登录”“页面标题”,配置时在路由规则中加 meta

{
  path: '/profile',
  component: ProfileView,
  meta: { 
    requiresAuth: true, // 是否需要鉴权 '个人中心' // 页面标题
  }
}

使用场景:

  • 全局守卫中统一处理页面标题
    router.beforeEach((to) => {
    if (to.meta.title) {
      document.title = to.meta.title
    }
    })
  • 权限验证:结合 to.meta.requiresAuth 判断是否需要登录(如问题6的示例),让权限逻辑和路由配置解耦,维护更方便。

问题8:路由懒加载怎么实现?对性能有啥帮助?
路由懒加载是“组件按需加载”,减少首屏加载体积(初始只加载首页等核心资源,访问对应路由时再加载组件),Vue Router 4 用动态 import() 实现:

{
  path: '/about',
  component: () => import('../views/AboutView.vue') // 访问 /about 时才加载组件
}

构建工具(如 Webpack、Vite)会把懒加载组件单独打包成 chunk,访问对应路由时再请求该 chunk,还能结合 Vue 的 <Suspense> 组件做加载状态:

<template>
  <Suspense>
    <template #default>
      <router-view></router-view> <!-- 渲染匹配的组件 -->
    </template>
    <template #fallback>
      <div>加载中...</div> <!-- 组件加载时显示的占位符 -->
    </template>
  </Suspense>
</template>

这样既优化了首屏性能,又提升了用户体验(避免白屏)。

实战场景:Vue Router 4 怎么解决复杂需求?

问题9:多布局切换(比如前台/后台不同布局)怎么做?
场景:网站分“前台(首页、文章页)”和“后台(管理页面)”,布局完全不同,用动态组件 + 路由元信息实现:

  1. 定义布局组件LayoutFront.vue(前台布局)、LayoutAdmin.vue(后台布局)。

  2. 路由配置加 meta.layout

    routes: [
    {
     path: '/',
     name: 'home',
     component: HomeView,
     meta: { layout: 'front' } // 前台布局
    },
    {
     path: '/admin',
     component: AdminView,
     meta: { layout: 'admin' }, // 后台布局
     children: [...] // 后台子路由
    }
    ]
  3. 在 App.vue 动态渲染布局

    <template>
    <component :is="layoutComponent">
     <router-view></router-view>
    </component>
    </template>
```

这样不同路由会自动切换布局,代码结构更清晰。

问题10:路由错误处理(404 页面)怎么配置?
404 页面需匹配“所有未定义的路由”,因此要把通配符路由放在路由规则最后(路由匹配是“从上到下,一旦匹配就停止”),配置:

routes: [
  // 其他路由...
  {
    path: '/:pathMatch(.*)*', // Vue Router 4 通配符写法,匹配所有路径
    name: 'NotFound',
    component: () => import('../views/NotFoundView.vue')
  }
]

用户访问不存在的路径时,会跳转到 NotFoundView,可在该组件内加“返回首页”按钮,提升体验:

<template>
  <div>
    <h1>404 - 页面走丢了</h1>
    <button @click="goHome">返回首页</button>
  </div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goHome = () => router.push('/')
</script>

问题11:和 Pinia/Vuex 结合做权限控制,怎么设计?
以 Pinia 存储用户登录状态为例,在全局前置守卫中判断权限:

import { useUserStore } from '@/stores/user'
router.beforeEach((to) => {
  const userStore = useUserStore()
  // 如果路由需要鉴权,且用户未登录 → 跳登录页并携带重定向参数
  if (to.meta.requiresAuth && !userStore.isLogin) {
    return { name: 'login', query: { redirect: to.fullPath } }
  }
})

登录组件中,登录成功后跳转到“重定向参数”对应的路径:

import { useRouter, useRoute } from 'vue-router'
import { useUserStore } from '@/stores/user'
export default {
  setup() {
    const router = useRouter()
    const route = useRoute()
    const userStore = useUserStore()
    const handleLogin = () => {
      userStore.login() // 执行登录逻辑(比如存 token)
      const redirect = route.query.redirect || '/' // 优先跳转到原目标页
      router.push(redirect)
    }
    return { handleLogin }
  }
}

这种设计实现了“权限控制 + 重定向”的完整流程,用户体验更流畅。

学习资源与避坑指南

问题12:学 Vue Router 4 看什么资料?怎么避常见坑?

  • 学习资源

    • 官方文档:Vue Router 4 文档对概念、API、示例讲解极细,是权威参考。
    • 实战项目:做一个“带权限的后台管理系统”,覆盖动态路由、嵌套路由、守卫、懒加载、多布局等场景,把知识点落地。
  • 避坑指南

    1. 路由模式选择

      • History 模式:URL 美观(无 #),但需后端配置(如 Nginx 把所有请求转发到 index.html),否则刷新页面会 404。
      • Hash 模式:URL 带 #(如 http://xxx/#/about),无需后端配置,适合对 URL 美观度要求不高的项目。
    2. 动态路由参数监听
      动态路由复用组件时(如 /user/1/user/2),组件生命周期不触发,需用 watch 监听 route.params 或用 onBeforeRouteUpdate 守卫。

    3. 嵌套路由的 path 写法
      子路由的 path 不要加 ,否则会被解析为根路径(如 path: '/settings' 会变成 `/settings

版权声明

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

发表评论:

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

热门