Vue路由跳转是前端项目页面切换的核心操作,贯穿整个Vue项目开发(从简单页面跳转,到带参跳转、权限控制跳转)。本文将整合Vue2、Vue3路由跳转的所有常用方式,明确不同场景的使用选择,补充参数传递、导航守卫、常见问题及解决方案,提供可直接复制的实战示例,兼顾新手入门与实战适配。
一、Vue路由跳转核心前提(必看)
无论Vue2还是Vue3,路由跳转前需确保已完成路由配置(引入Vue Router、创建路由实例、挂载路由),基础配置如下(简化版,可直接复用):
javascript
// Vue2 基础路由配置(router/index.js)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{ path: '/', name: 'Home', component: () => import('../views/Home.vue') },
{ path: '/about', name: 'About', component: () => import('../views/About.vue') },
{ path: '/user/:id', name: 'User', component: () => import('../views/User.vue') }
]
const router = new VueRouter({ mode: 'history', routes })
export default router
// Vue3 基础路由配置(router/index.js)
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{ path: '/', name: 'Home', component: () => import('../views/Home.vue') },
{ path: '/about', name: 'About', component: () => import('../views/About.vue') },
{ path: '/user/:id', name: 'User', component: () => import('../views/User.vue') }
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
说明:Vue2需通过Vue.use(VueRouter)注册路由,Vue3通过createRouter创建路由实例,二者跳转语法有细微差异,下文将分别说明并标注适配版本。
二、Vue路由跳转3种核心方式(实战常用)
Vue路由跳转主要分为「声明式跳转」和「编程式跳转」,其中编程式跳转更灵活,可结合业务逻辑(如登录判断)使用,声明式跳转适合简单页面切换。
方式1:声明式跳转( 标签,最简洁)
核心:通过Vue Router提供的<router-link>标签实现跳转,无需写JS逻辑,自动渲染为a标签(可通过tag属性修改标签类型),适配Vue2、Vue3,用法完全一致。
1. 基础跳转(无参数)
xml
<!-- 方式1:通过path跳转(推荐,简洁直观) -->
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<!-- 方式2:通过name跳转(需配置路由name,适合路径较长场景) -->
<router-link :to="{ name: 'Home' }">首页</router-link>
<router-link :to="{ name: 'About' }">关于我们</router-link>
<!-- 可选:修改渲染标签(默认a标签,改为button) -->
<router-link to="/" tag="button">首页(按钮形式)</router-link>
2. 带参数跳转(query参数 / params参数)
跳转时传递参数,用于页面间数据交互,两种参数类型用法不同,需区分场景:
xml
<!-- 1. query参数(暴露在URL上,可刷新保留,适合简单数据) -->
<!-- 方式:path/name + query对象 -->
<router-link :to="{ path: '/user', query: { id: 1, name: '张三' } }">
进入用户页(query参数)
</router-link>
<router-link :to="{ name: 'User', query: { id: 1, name: '张三' } }">
进入用户页(name+query)
</router-link>
<!-- 跳转后URL:http://localhost:8080/user?id=1&name=张三 -->
<!-- 2. params参数(不暴露在URL上,刷新丢失,适合敏感数据) -->
<!-- 注意:params必须配合name跳转,不能配合path -->
<router-link :to="{ name: 'User', params: { id: 1, name: '张三' } }">
进入用户页(params参数)
</router-link>
<!-- 跳转后URL:http://localhost:8080/user/1(需配置路由path为/user/:id) -->
方式2:编程式跳转(router.push / router.replace,最灵活)
核心:通过JS代码调用router.push(保留历史记录)或router.replace(不保留历史记录,无法返回上一页)实现跳转,适合结合业务逻辑(如登录成功后跳转、按钮点击跳转),Vue2和Vue3用法略有差异。
1. Vue2 编程式跳转
php
// 1. 基础跳转(无参数)
this.$router.push('/') // path跳转
this.$router.push({ name: 'Home' }) // name跳转
// 2. 带参数跳转(query / params)
// query参数
this.$router.push({
path: '/user',
query: { id: 1, name: '张三' }
})
// params参数(需配合name)
this.$router.push({
name: 'User',
params: { id: 1, name: '张三' }
})
// 3. 替换跳转(不保留历史记录)
this.$router.replace('/about')
// 4. 后退/前进(操作历史记录)
this.$router.go(-1) // 后退1页(类似浏览器返回键)
this.$router.back() // 等同于go(-1)
this.$router.go(1) // 前进1页
2. Vue3 编程式跳转
Vue3 setup语法中,无this,需通过useRouter引入路由实例,用法如下:
php
// 1. 引入路由实例(必须先引入)
import { useRouter } from 'vue-router'
const router = useRouter()
// 2. 基础跳转(无参数)
router.push('/')
router.push({ name: 'Home' })
// 3. 带参数跳转(query / params)
router.push({
path: '/user',
query: { id: 1, name: '张三' }
})
router.push({
name: 'User',
params: { id: 1, name: '张三' }
})
// 4. 替换跳转(不保留历史记录)
router.replace('/about')
// 5. 后退/前进
router.go(-1)
router.back()
router.go(1)
方式3:路由重定向(redirect,自动跳转)
核心:在路由配置中通过redirect属性,实现页面自动跳转(无需用户操作),适合默认页面、404页面、旧路径跳转新路径场景,Vue2、Vue3用法一致。
arduino
// 路由配置中添加redirect
const routes = [
// 1. 默认跳转(访问根路径,自动跳转到首页)
{ path: '/', redirect: '/home' },
// 2. 通过name重定向
{ path: '/index', redirect: { name: 'Home' } },
// 3. 旧路径跳转新路径(兼容旧链接)
{ path: '/old-user', redirect: '/user' },
// 4. 404页面(匹配所有未定义路径,跳转到404组件)
{ path: '/:pathMatch(.*)*', redirect: '/404' }
]
三、路由跳转参数接收(配套必备)
跳转时传递的query/params参数,需在目标页面接收后使用,Vue2和Vue3接收方式不同,以下是完整示例:
1. Vue2 参数接收
javascript
// 1. 接收query参数
export default {
mounted() {
const id = this.$route.query.id // 接收query参数id
const name = this.$route.query.name // 接收query参数name
console.log(id, name) // 输出:1 张三
}
}
// 2. 接收params参数
export default {
mounted() {
const id = this.$route.params.id // 接收params参数id
const name = this.$route.params.name // 接收params参数name
console.log(id, name) // 输出:1 张三
}
}
2. Vue3 参数接收
Vue3 setup语法中,需通过useRoute引入路由对象,接收参数:
csharp
// 引入路由对象
import { useRoute } from 'vue-router'
const route = useRoute()
// 接收参数(可在setup中直接使用,或在生命周期中使用)
const id = route.query.id // query参数
const name = route.query.name
const paramsId = route.params.id // params参数
const paramsName = route.params.name
console.log(id, paramsId) // 输出:1 1
四、路由跳转进阶:导航守卫(权限控制)
实际开发中,常需要对路由跳转进行权限控制(如未登录不能访问个人中心),此时需使用导航守卫,拦截跳转并判断权限,Vue2、Vue3用法基本一致,以下是实战示例:
1. 全局导航守卫(控制所有路由跳转)
javascript
// Vue2 全局导航守卫(router/index.js)
router.beforeEach((to, from, next) => {
// to:目标路由对象
// from:当前跳转前的路由对象
// next:放行/拦截方法
// 示例:未登录不能访问/user路径
const token = localStorage.getItem('token') // 模拟登录状态
if (to.path === '/user' && !token) {
next('/login') // 未登录,拦截并跳转到登录页
} else {
next() // 已登录,放行
}
})
// Vue3 全局导航守卫(用法完全一致)
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
if (to.meta.requireAuth && !token) { // 结合路由元信息,更灵活
next('/login')
} else {
next()
}
})
// 路由元信息配置(标记需要权限的路由)
const routes = [
{
path: '/user',
name: 'User',
component: () => import('../views/User.vue'),
meta: { requireAuth: true } // 标记:需要登录才能访问
}
]
2. 组件内导航守卫(控制单个组件跳转)
仅对当前组件的跳转进行拦截,适合单个组件的特殊权限控制:
javascript
// Vue2 组件内守卫
export default {
// 进入组件前拦截
beforeRouteEnter(to, from, next) {
const token = localStorage.getItem('token')
if (!token) {
next('/login')
} else {
next()
}
},
// 离开组件前拦截(如提示用户未保存内容)
beforeRouteLeave(to, from, next) {
if (confirm('确定要离开吗?内容未保存')) {
next()
} else {
next(false) // 取消跳转
}
}
}
// Vue3 组件内守卫(setup语法)
import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router'
// 进入组件前拦截
onBeforeRouteEnter((to, from, next) => {
const token = localStorage.getItem('token')
if (!token) {
next('/login')
} else {
next()
}
})
// 离开组件前拦截
onBeforeRouteLeave((to, from, next) => {
if (confirm('确定要离开吗?内容未保存')) {
next()
} else {
next(false)
}
})
五、路由跳转常见问题及解决方案
1. 跳转后页面不刷新
原因:路由参数变化(如从/user/1跳转到/user/2),组件会复用,不会重新触发mounted生命周期。
解决方案:监听路由变化,触发数据重新请求:
javascript
// Vue2 监听路由
watch: {
'$route'(to, from) {
// 路由变化时,重新请求数据
this.getUserData(to.params.id)
}
}
// Vue3 监听路由
import { watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
watch(
() => route.params,
(newParams) => {
// 监听params变化,重新请求数据
getUserData(newParams.id)
},
{ deep: true }
)
2. params参数刷新后丢失
原因:params参数不暴露在URL上,页面刷新后,路由信息重置,参数丢失。
解决方案:1. 改用query参数(适合非敏感数据);2. 将params参数存储到localStorage/sessionStorage,刷新后重新读取。
3. 路由跳转后,URL正确但页面空白
常见原因:1. 路由配置错误(path拼写错误、component路径错误);2. 未在页面中添加<router-view>标签(路由出口,用于渲染跳转后的组件)。
解决方案:核对路由path和component路径,确保App.vue中包含<router-view>:
xml
<!-- App.vue 必须添加路由出口 -->
<template>
<div id="app">
<router-link to="/">首页</router-link>
<router-view /> <!-- 路由跳转后的组件会渲染在这里 -->
</div>
</template>
4. Vue3中报错"Cannot read property 'push' of undefined"
原因:Vue3 setup语法中,未通过useRouter引入路由实例,直接使用this.$router(setup中无this)。
解决方案:正确引入useRouter,创建路由实例后再使用:
javascript
// 正确用法
import { useRouter } from 'vue-router'
const router = useRouter()
router.push('/about') // 无报错
六、总结
Vue路由跳转核心分为3种方式,结合场景选择即可:
- 简单页面切换:用声明式跳转() ,简洁高效;
- 需结合业务逻辑(登录、判断):用编程式跳转(router.push) ,灵活可控;
- 自动跳转(默认页、404):用路由重定向(redirect) ,无需用户操作。
关键注意点:Vue2和Vue3的跳转语法差异主要在"是否使用this",Vue3需通过useRouter/useRoute引入路由实例和路由对象;参数传递需区分query(刷新保留)和params(刷新丢失);权限控制用导航守卫,避免未授权访问。
本文所有示例均可直接复制到项目中使用,只需根据自身项目的路由配置,修改路径和组件名称即可快速适配。