vue-router解决警告:No match found for location with path "XXXXXXX"
使用vue-router时,在刷新页面时往往会出现这个警告:
这个问题产生的原因往往是因为vue在启动时,会校验当前页面的路由,而我们使用vue-router时,是在导航守卫中动态添加路由的,因此肯定找不到,而这个时候还没进入守卫,自然就会抛出这个警告了:
1、app.use(router)
2、router.install(app)
3、push(routerHistory.location)
4、pushWithRedirect(to)
5、resolve(to)
resolve函数部分代码如下:
function resolve(rawLocation, currentLocation) {
// const objectLocation = routerLocationAsObject(rawLocation)
// we create a copy to modify it later
currentLocation = assign({}, currentLocation || currentRoute.value);
if (typeof rawLocation === 'string') {
const locationNormalized = parseURL(parseQuery$1, rawLocation, currentLocation.path);
const matchedRoute = matcher.resolve({ path: locationNormalized.path }, currentLocation);
const href = routerHistory.createHref(locationNormalized.fullPath);
if ((process.env.NODE_ENV !== 'production')) {
if (href.startsWith('//'))
warn(`Location "${rawLocation}" resolved to "${href}". A resolved location cannot start with multiple slashes.`);
else if (!matchedRoute.matched.length) {
warn(`No match found for location with path "${rawLocation}"`);
}
}
// locationNormalized is always a new object
return assign(locationNormalized, matchedRoute, {
params: decodeParams(matchedRoute.params),
hash: decode(locationNormalized.hash),
redirectedFrom: undefined,
href,
});
}
//省略...
}
其中rawLocation就是routerHistory.location,其实就是location.pathname+location.search+location.hash,因为路由是在守卫中动态添加的,这里matcher.resolve自然就匹配不到路由了,因为此时项目才启动,还没进入守卫中。
虽然这个可能不会对我们的功能有什么大的影响,但是我们还是可以从根本上处理掉它,让我们应用更加完善。
解决办法
这个问题的一个解决思路:
1、创建router时,添加一个全局的路由,一般可以取名为404,表示没有匹配到路由
2、当页面刷新时,resolve函数中matcher.resolve未匹配到正确路由时,就会匹配到这个404的路由
3、因为有匹配到路由,所以就不会有警告,接着进入守卫
4、在守卫中从后端获取数据,动态构建路由
5、然后对404路由的路由进行重定向
1、添加404路由:
// 静态路由
export const constantRouterMap = [
{
name: 'root',
path: '/',
redirect: '/welcome',
component: AppLayout,
children: [
{
path: 'welcome',
name: 'welcome',
component: () => import(`@/views/welcome/index.vue`),
meta: {
title: 'Welcome'
}
}
]
},
{
name: '404',
path: '/:catchAll(.*)',
component: () => import(`@/views/error/404.vue`)
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: constantRouterMap
})
2、守卫中假如判断
// 进入路由前的过滤器
router.beforeEach((to, from, next) => {
//省略其它代码...
//判断是否登录
const token = getToken()
if (token) {
const routes = getRoutes()
//路由是否存在
if (!routes) {
//不存在则从远程获取
getUserInfo().then(res => {
//创建路由routes
// 动态添加可访问路由表
routes.forEach(r => {
router.addRoute(r)
})
//表示要做一次重定向
if (to.name === '404') {
next({ path: to.path, query: to.query })
} else {
// 请求带有 redirect 重定向时,登录自动重定向到该地址
if (from.query.redirect) {
const redirect = decodeURIComponent(from.query.redirect)
next({ path: redirect })
} else {
next({ ...to, replace: true })
}
}
//省略其它代码...
})
} else { //存在则跳过
//省略其它代码...
next()
}
} else {
next({ name: 'login', query: { redirect: to.fullPath } })
}
//省略其它代码...
})
这样,刷新页面警告也不会出现了
一个专注于.NetCore的技术小白