1.路由配置项写错,页面空白或跳转没反应
p>在Vue项目里,路由功能基本靠Vue Router来实现,但开发时稍不注意就会碰到各种路由错误,像页面突然空白、跳转没反应、刷新就白屏这些情况,特别影响开发效率,下面就把Vue Router开发中常见的错误场景一个个拆解,讲讲咋分析原因、咋解决~
路由配置是Vue Router的基础,可要是
path、component这些关键配置写错,页面要么空白,要么点了没反应。
常见错误点1:component拼写或引用错误
很多同学会把component写成components(多了个s),或者直接把组件名当字符串写,
// 错误写法:component写成components,或者组件没正确引入
const router = new VueRouter({
routes: [
{
path: '/home',
components: Home // 这里多了s,而且Home没导入的话也会错
}
]
})
正确做法是先导入组件(不管是静态导入还是懒加载),再把component值设为组件对象:
// 静态导入
import Home from '@/views/Home.vue'
// 懒加载
const About = () => import('@/views/About.vue')
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home // 注意是component单数
},
{
path: '/about',
component: About // 懒加载语法要对
}
]
})
常见错误点2:路由顺序搞反,通配符没放最后
Vue Router是按路由配置顺序匹配的,要是把通配符(匹配404页面)放在前面,后面的路由就永远匹配不到了。
// 错误顺序:404路由在前面,导致/home也会匹配到*
const router = new VueRouter({
routes: [
{ path: '*', component: Error404 },
{ path: '/home', component: Home }
]
})
得把通配符路由放到所有路由的最后,保证精确匹配的路由先生效:
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/about', component: About },
{ path: '*', component: Error404 } // 最后放404
]
})
常见错误点3:path拼写错误或层级不对
比如想跳转到/user/profile,结果path写成/user/proflie(拼写错),或者嵌套路由里父路由path没写对,导致子路由匹配失败,这时候得逐行检查路由配置的path,可以结合Vue DevTools的“Routes”面板,看当前匹配的路由是否符合预期。
导航守卫逻辑乱,路由拦截失效或死循环
导航守卫(比如beforeEach、beforeRouteEnter)用来控制路由权限、页面跳转逻辑,但逻辑写不对就会出问题。
错误场景1:next()没调用或调用多次
全局前置守卫beforeEach里,必须确保每个分支都调用next(),否则路由会卡在半路上,比如权限判断时漏掉else分支:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
if (isLogin()) {
next() // 登录了放行
} else {
next('/login') // 没登录跳登录
}
}
// 这里漏掉:如果路由不需要权限,也要调用next()
})
正确写法是覆盖所有情况,比如加个else或者在最后调用next():
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
if (isLogin()) {
next()
} else {
next('/login')
}
} else {
next() // 不需要权限的路由直接放行
}
})
next()不能调用多次,比如在异步操作里重复调用:
router.beforeEach((to, from, next) => {
axios.get('/api/checkAuth').then(res => {
next() // 第一次调用
})
next() // 第二次调用,会报错
})
要把异步里的next()逻辑理顺,用async/await或者Promise控制流程。
错误场景2:全局守卫和组件内守卫冲突
比如全局beforeEach里做了权限拦截,组件内beforeRouteEnter又做了重复判断,导致逻辑混乱,这时候要理清守卫的执行顺序(全局前置→路由独享→组件内beforeRouteEnter),把权限逻辑集中在全局守卫,组件内守卫处理组件级的逻辑(比如表单未保存阻止跳转)。
动态路由匹配时,页面不更新或参数拿错
动态路由(如/user/:id)能根据不同参数渲染同一组件,但组件复用会导致生命周期不触发,参数也可能拿错。
问题表现:
从/user/1跳转到/user/2,页面数据没变化,因为组件实例被复用了,created这些钩子不会重新执行。
解决方法1:用watch监听$route变化
在组件里监听$route,参数变化时更新数据:
export default {
data() {
return {
userId: ''
}
},
watch: {
'$route'(to, from) {
this.userId = to.params.id // 当id变化时更新
this.fetchUser() // 重新请求数据
}
},
mounted() {
this.fetchUser()
},
methods: {
fetchUser() {
// 根据this.userId请求数据
}
}
}
解决方法2:用组件内守卫beforeRouteUpdate
这个守卫在路由参数变化但组件复用时触发:
export default {
beforeRouteUpdate(to, from, next) {
this.userId = to.params.id
this.fetchUser()
next() // 记得调用next()放行
}
}
路由模式不兼容,部署后刷新白屏或404
Vue Router有hash和history两种模式,配置不对在生产环境容易出问题。
场景1:history模式下,刷新页面报404
history模式靠HTML5的history.pushState实现,部署到服务器后,刷新页面时服务器会直接请求/user/1这样的路径,但服务器没对应的资源,就返回404。
解决方法是让服务器把所有路由请求转发到index.html,比如用Nginx配置:
location / {
try_files $uri $uri/ /index.html;
}
这样不管请求哪个路径,都会回到Vue的入口文件,由前端路由处理。
场景2:hash模式下,锚点被手动修改导致路由错乱
hash模式的URL长这样:http://xxx.com/#/home,如果用户手动把后面的内容改掉(比如改成#/hom),路由就会匹配错误,所以要避免用户手动修改锚点,所有路由跳转都用router.push、router.replace等方法,不要手动改window.location.hash。
路由懒加载失败,打包或加载报错
路由懒加载能减小首屏体积,但配置不对会导致chunk加载失败。
错误点1:webpack或babel配置不对
如果用Vue CLI创建的项目,默认支持懒加载,但如果自己配webpack,要确保babel-loader处理了懒加载的文件,并且开启了代码分割,比如webpack配置里要有:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
Babel要配置@babel/plugin-syntax-dynamic-import来支持() => import()语法。
错误点2:懒加载语法写错
正确的懒加载是const Home = () => import('@/views/Home.vue'),要是写成const Home = import('@/views/Home.vue')(少了箭头函数),就会变成静态导入,还可能报错。
错误点3:网络问题导致chunk加载失败
用户网络差时,懒加载的chunk可能加载失败,可以给Vue Router加错误处理:
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
或者在路由组件里用errorCaptured处理加载错误。
嵌套路由配置错,子路由不渲染
嵌套路由需要父组件里有<router-view>,否则子路由组件没地方渲染。
错误案例:
父路由配置了children,但父组件Home.vue里没写<router-view>:
// 路由配置
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
children: [
{ path: 'news', component: News }
]
}
]
})
// Home.vue(错误,没<router-view>)
<template>
<div>
<h1>Home页面</h1>
</div>
</template>
这时候访问/home/news,News组件不会渲染。解决方法是在父组件加<router-view>:
<template>
<div>
<h1>Home页面</h1>
<router-view></router-view> <!-- 子路由渲染的地方 -->
</div>
</template>
子路由的path不要加斜杠,比如children里写path: '/news'会变成根路径下的/news,而不是/home/news,要改成path: 'news'(继承父路由的path)。
路由名称或路径重复,跳转混乱
路由的name和同层级的path必须唯一,否则会冲突。
场景1:name重复导致命名路由跳转错误
比如两个路由都叫'user':
const router = new VueRouter({
routes: [
{ path: '/user', name: 'user', component: UserList },
{ path: '/user/:id', name: 'user', component: UserDetail } // 重复name
]
})
用router.push({ name: 'user' })时,不知道该跳哪个,要给每个路由唯一的name,比如改成'userList'和'userDetail'。
场景2:同层级path重复
在同一父路由的children里,path不能重复(动态路由除外,比如/user/:id和/user/:name算不同路由,但实际开发少这么用),要确保每个路由的path在同层级唯一。
404页面不显示或重定向循环
404页面靠通配符实现,但配置不对就不显示;重定向写循环会导致页面无限跳转。
404配置错误:
通配符路由没放最后,导致被前面的路由拦截。
const router = new VueRouter({
routes: [
{ path: '*', component: Error404 },
{ path: '/home', component: Home }
]
})
访问/home时,先匹配到,所以永远到不了Home页面,要把路由放最后。
重定向循环:
比如A重定向到B,B又重定向到A:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' },
{ path: '/b', redirect: '/a' }
]
})
这会导致无限重定向,浏览器报错,要检查重定向链条,确保是单向的,比如/a→/b→/c这种线性结构。
路由传参丢失或解析错
用params或query传参时,稍不注意参数就丢了或解析错。
params传参刷新丢失
params是基于路由配置的动态段(如/user/:id),如果路由没配置动态段,用params传参,刷新后参数会丢失。
// 路由没配:id
{ path: '/user', component: User }
// 传参
router.push({ name: 'user', params: { id: 1 } })
刷新后$route.params.id就没了。解决方法:要么把path改成/user/:id(动态路由),要么用query传参(query参数在URL里,刷新不丢),或者把params存到sessionStorage里。
query传参格式错误
如果传对象给query,
router.push({
path: '/search',
query: { keywords: { name: 'vue', type: 'framework' } }
})
URL会变成/search?keywords=[object%20Object],解析时出错,要把对象转成字符串,比如用JSON.stringify:
router.push({
path: '/search',
query: {
keywords: JSON.stringify({ name: 'vue', type: 'framework' })
}
})
// 接收时解析
const keywords = JSON.parse(this.$route.query.keywords)
传参时拼写错误
比如想传userId,结果写成userID(大小写错),或者路由里的path是/profile,跳转时写成/proflie(拼写错),要仔细检查参数名和路由路径的拼写。
上面这些就是Vue Router开发中常见的错误和解决办法啦~其实很多错误都是配置细节、逻辑顺序或者语法的小问题,开发时多结合Vue DevTools看路由状态,控制台看报错信息,再对照路由配置一步步排查,基本都能解决~要是碰到没见过的错误,也可以去Vue Router官方文档翻一翻,里面对每个API和配置的说明都很详细,能帮你理清逻辑~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网




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