还在手动处理页面跳转?掌握Vue Router 4,你的导航效率翻倍!

朋友们,你们有没有在开发Vue应用时,对着页面跳转和权限管理头疼过?手动拼接URL?自己处理前进后退?用户没登录也能进入管理后台?别担心,今天我们就来彻底搞定Vue Router 4。

Vue Router是Vue.js官方的路由管理器,它能让你用组件化的思维来管理你的页面和视图。说白了,就是让你的单页面应用看起来像是有很多个"页面"一样,并且能无缝地在它们之间跳转。从基础的路径配置到高级的导航守卫,这篇文章会带你从零开始,快速上手。相信我,学完它,你的开发体验会顺畅得多。

先让你的项目"动"起来:安装与基础配置

第一步,我们得把它请进项目里。打开你的终端,在你Vue项目的根目录下,运行这条命令。假设你用的是Vue 3项目。

bash 复制代码
npm install vue-router@4

安装好了,我们就来创建路由的核心------路由实例。通常,我们会在一个单独的src/router/index.js文件中做这件事。跟着下面的代码走一遍,你就明白了。

javascript 复制代码
// src/router/index.js
// 1. 导入必要的函数和组件
import { createRouter, createWebHistory } from 'vue-router'
// 2. 导入你希望成为"页面"的Vue组件
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'

// 3. 定义路由规则数组
const routes = [
  {
    path: '/', // 当浏览器地址是根路径时
    name: 'home', // 给路由起个名字,方便跳转
    component: HomeView // 显示HomeView这个组件
  },
  {
    path: '/about',
    name: 'about',
    component: AboutView
  }
]

// 4. 创建路由实例
const router = createRouter({
  // 使用HTML5的历史模式,URL看起来更干净(比如 /about)
  // 另一种模式是 createWebHashHistory,URL会带#号
  history: createWebHistory(),
  routes // 简写,等同于 routes: routes
})

// 5. 导出这个实例,在main.js中会用到
export default router

创建好路由实例后,我们需要告诉Vue应用去使用它。找到你的应用入口文件src/main.js,像下面这样修改。

javascript 复制代码
// 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')

最后一步,我们得在根组件App.vue里放一个"插座",路由匹配到的组件就会在这个"插座"里显示出来。

vue 复制代码
<!-- src/App.vue -->
<template>
  <div id="app">
    <nav>
      <!-- 使用 router-link 组件进行导航,它会被渲染成一个 <a> 标签 -->
      <router-link to="/">首页</router-link> |
      <router-link to="/about">关于</router-link>
    </nav>
    <!-- 路由匹配到的组件将在这里被渲染,这就是那个"插座" -->
    <router-view />
  </div>
</template>

好了!现在运行你的项目,点击"首页"和"关于",你应该能看到页面内容在<router-view />的位置切换了,而浏览器地址栏的URL也会跟着变化。恭喜,你的第一个带路由的Vue应用跑通了!

进阶导航:如何在不同页面间穿梭

光能显示页面还不够,我们常常需要在代码里控制跳转,比如登录成功后自动跳转到主页。有两种主要方式。

第一种,声明式导航 。就像上面的例子,我们用<router-link>标签。它比用<a href="...">好在,它是在单页面应用内部跳转,不会真的向服务器重新加载页面,速度飞快。

vue 复制代码
<template>
  <!-- 使用'to'属性指定目标地址,可以是字符串路径,也可以是路由对象 -->
  <router-link to="/about">去关于页面</router-link>

  <!-- 更推荐使用命名路由,这样即使你改了path路径,这里的链接也不用改 -->
  <router-link :to="{ name: 'home' }">返回首页</router-link>

  <!-- 甚至可以带参数 -->
  <router-link :to="{ name: 'user', params: { id: 123 } }">查看用户123</router-link>
</template>

第二种,编程式导航 。在你的组件方法里,通过this.$router(在组合式API中是useRouter())来跳转。这给了你最大的灵活性。

vue 复制代码
<script>
// 选项式 API 写法
export default {
  methods: {
    goToAboutPage() {
      // 和 router-link 的 `to` 属性一样,可以接受路径或路由对象
      this.$router.push('/about')
      // 或者
      this.$router.push({ name: 'about' })
    },
    goBack() {
      // 返回上一页,相当于浏览器的后退按钮
      this.$router.back()
    },
    replaceHome() {
      // 用'替换'的方式跳转,不会在历史记录里留下当前页
      this.$router.replace({ name: 'home' })
    }
  }
}
</script>
vue 复制代码
<script setup>
// 组合式 API 写法(现在更常用)
import { useRouter } from 'vue-router'

const router = useRouter()

const goToAboutPage = () => {
  router.push('/about')
}
const goBack = () => {
  router.back()
}
</script>

让路由活起来:动态路由与参数传递

很多时候,我们的路径不是固定的,比如用户详情页/user/1/user/2。这就需要动态路由。

javascript 复制代码
// 在路由规则中,用冒号 : 来标记动态部分
const routes = [
  {
    path: '/user/:id', // `:id`就是一个动态参数
    name: 'user',
    component: UserView
  }
]

在目标组件UserView.vue里,我们怎么拿到这个id呢?通过useRoute()这个函数。

vue 复制代码
<!-- src/views/UserView.vue -->
<template>
  <div>
    <h2>用户详情页</h2>
    <!-- 在模板中直接使用 -->
    <p>当前用户ID是:{{ $route.params.id }}</p>
    <p>另一种方式获得的ID:{{ userId }}</p>
  </div>
</template>

<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'

// 使用 useRoute() 获取当前路由信息
const route = useRoute()

// 动态参数是响应式的,我们可以用计算属性来获取
const userId = computed(() => route.params.id)

// 你也可以通过 route.query 获取查询参数
// 比如 /user/123?name=zhangsan,则 route.query.name 为 'zhangsan'
const userName = computed(() => route.query.name)
</script>

除了通过URL(params, query)传递参数,你还可以用props传参,让组件更干净。

javascript 复制代码
// 在路由规则中开启 props 传参
const routes = [
  {
    path: '/user/:id',
    name: 'user',
    component: UserView,
    props: true // 将 route.params 作为组件的 props 传入
    // 或者使用函数模式,实现更灵活的控制
    // props: (route) => ({ id: Number(route.params.id) })
  }
]

然后你的组件就可以像接收普通props一样接收它了。

vue 复制代码
<!-- src/views/UserView.vue -->
<script setup>
// 直接定义 props
defineProps({
  id: {
    type: [String, Number],
    required: true
  }
})
</script>

<template>
  <div>用户ID是:{{ id }}</div>
</template>

项目的"守门神":路由守卫深度解析

重头戏来了!路由守卫是Vue Router里非常强大的一环,它允许你在导航发生前、发生后进行拦截或处理。最常见的场景就是:检查用户是否登录。

全局前置守卫router.beforeEach:这是最常用的守卫,在每一次导航开始时触发。我们可以在这里做权限检查。

javascript 复制代码
// 回到你的 src/router/index.js
// 在创建并导出 router 实例之后,可以添加守卫

// ... createRouter 代码 ...

// 添加全局前置守卫
router.beforeEach((to, from, next) => {
  // to: 即将要进入的目标路由对象
  // from: 当前导航正要离开的路由对象
  // next: 一个函数,必须调用它来解析这个守卫

  // 假设我们有一个简单的登录检查
  const isAuthenticated = localStorage.getItem('token') // 从本地存储读取token

  // 如果用户想去一个需要登录的页面(比如页面元信息里标记了 requiresAuth: true)
  if (to.meta.requiresAuth && !isAuthenticated) {
    // 把他重定向到登录页
    next({
      name: 'login',
      // 可以附带一个查询参数,记录他原本想去哪里,登录后直接跳过去
      query: { redirect: to.fullPath }
    })
  } else {
    // 放行,去往目标页面
    next()
  }
})

路由独享的守卫beforeEnter:你可以只为某一条路由规则定义守卫,它只在进入该路由时触发。

javascript 复制代码
const routes = [
  {
    path: '/admin',
    name: 'admin',
    component: AdminView,
    meta: { requiresAdmin: true }, // 自定义元信息,标记需要管理员权限
    beforeEnter: (to, from, next) => {
      const userRole = getUserRoleSomehow() // 假设有个获取用户角色的方法
      if (userRole === 'admin') {
        next() // 是管理员,允许进入
      } else {
        next({ name: 'forbidden' }) // 不是管理员,跳转到无权限页面
      }
    }
  }
]

组件内的守卫:你还可以在组件内部定义守卫。

  • onBeforeRouteUpdate:当前组件复用时(仅参数变化)调用,非常适合用来根据新参数获取数据。
  • onBeforeRouteLeave:离开该组件时调用,可以用来防止用户在编辑表单时误操作离开。
vue 复制代码
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

// 守卫1:离开组件前提示用户
onBeforeRouteLeave((to, from) => {
  const answer = window.confirm('你有未保存的更改,确定要离开吗?')
  // 如果用户取消,就取消这次导航
  if (!answer) return false
})

// 守卫2:当路由更新(比如从 /user/1 跳转到 /user/2)时,重新获取数据
import { fetchUserData } from '@/api'
onBeforeRouteUpdate(async (to) => {
  // 组件实例复用,但参数从 1 变成了 2
  // 在这里用新的参数 to.params.id 重新获取用户数据
  await fetchUserData(to.params.id)
})
</script>

最后:几条让你走得更远的实战建议

看到这里,你已经掌握了Vue Router 4的核心技能。为了让你的项目结构更清晰、代码更健壮,这里还有几个小贴士:

用好路由元信息meta字段:这个字段就像给你的路由贴标签,非常适合在全局守卫里做统一的权限判断,或者在生成导航菜单时标记是否需要显示。

考虑路由懒加载:当你的应用页面很多时,把所有组件的代码打包到一个文件里会让首次加载很慢。路由懒加载可以让你在访问某个页面时才去加载它的代码,大幅提升首屏速度。

javascript 复制代码
const routes = [
  {
    path: '/about',
    name: 'about',
    // 使用动态 import 语法,Webpack/Vite会自动进行代码分割
    component: () => import('../views/AboutView.vue')
  }
]

处理好404页面 :在路由规则的最后,添加一个通配符*的路由,来捕获所有未匹配的路径,展示一个友好的404页面。

javascript 复制代码
const routes = [
  // ... 你的其他路由 ...
  {
    path: '/:pathMatch(.*)*', // 这是Vue Router 4的捕获所有路由的写法
    name: 'not-found',
    component: () => import('../views/NotFoundView.vue')
  }
]

好了,我们从最基础的安装配置,一路聊到了动态参数和强大的路由守卫。现在回头看看,页面跳转、权限控制这些让人头疼的问题,是不是都有了清晰的解决思路?

关键在于动手去试。创建一个新项目,把这些代码示例都敲一遍,再试着结合你的实际业务(比如从后端API获取用户权限,动态生成路由),你就能真正驾驭Vue Router,让它成为你构建复杂单页面应用的得力助手。别再手动处理那些繁琐的导航逻辑了,让Vue Router来帮你,效率提升真的不止一点点。

相关推荐
xxy-mm7 小时前
Javascript 中的继承
开发语言·javascript·ecmascript
锋行天下9 小时前
公司内网部署大模型的探索之路
前端·人工智能·后端
1024肥宅9 小时前
手写 EventEmitter:深入理解发布订阅模式
前端·javascript·eventbus
海市公约11 小时前
HTML网页开发从入门到精通:从标签到表单的完整指南
前端·ide·vscode·程序人生·架构·前端框架·html
3秒一个大11 小时前
HTML5 与 JavaScript 中的二进制数据处理:ArrayBuffer 与 TextEncoder/Decoder 实践
javascript
purpleseashell_Lili11 小时前
如何学习 AG-UI 和 CopilotKit
javascript·typescript·react
行云流水62611 小时前
前端树形结构实现勾选,半勾选,取消勾选。
前端·算法
diudiu_3311 小时前
web漏洞--认证缺陷
java·前端·网络
阿珊和她的猫12 小时前
<video>` 和 `<audio>` 标签的常用属性解析
前端