朋友们,你们有没有在开发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来帮你,效率提升真的不止一点点。