背景
在使用 Vue 3 主项目 + Vue 2 子项目 的微前端架构中,我们遇到了一些路由跳转时的问题。具体表现为,点击跳转时,浏览器控制台会报错:
SyntaxError: Failed to execute 'replace' on 'Location': 'http://localhost:3333undefined' is not a valid URL.
根据错误堆栈信息,问题发生在 vue-router.mjs
文件的 changeLocation
函数中。通过进一步分析源码,我们发现是由于 currentState.current
为 undefined
导致的错误。
问题分析
在 vue-router
的实现中,history.state
对象的 current
属性是用来存储当前页面路径的。但是,某些情况下,当 current
属性未定义时,调用 replaceState
方法会导致无效的 URL,从而抛出 SyntaxError
错误。经过调试,我们确认这个问题出现在 Vue 3 主项目与 Vue 2 子项目之间的路由冲突中。
解决办法
为了避免 current
为 undefined
导致的错误,我们可以在 Vue 3 主项目的路由配置中手动为 current
属性赋值,从而确保跳转时的 URL 是有效的。
解决方案
- 在 Vue 3 主项目的
router/index.js
文件中,添加如下代码,确保每次路由跳转时,current
状态被正确设置。
import { assign, isEmpty } from 'lodash-es'
// 这段代码放到router定义之后
router.beforeEach((to, from, next) => {
if (isEmpty(history.state.current)) {
assign(history.state, { current: from.fullPath })
}
next()
})
代码解释
-
isEmpty(history.state.current)
:检查history.state.current
是否为空(即undefined
或null
)。 -
assign(history.state, { current: from.fullPath })
:如果current
为空,则手动将from.fullPath
(当前路由的完整路径)赋值给history.state.current
,确保跳转时有一个有效的历史状态。 -
next()
:调用next()
继续进行路由跳转。
通过这样的处理,确保每次跳转时都有有效的历史状态,从而避免出现无效 URL 的错误。
总结
在 Vue 3 主项目与 Vue 2 子项目共存的微前端架构中,路由跳转时出现 replaceState
错误是由于 history.state.current
未定义引起的。通过在主项目的路由配置中添加简单的检查与赋值逻辑,可以有效避免该问题,确保路由跳转的正常进行。
你可以查看关于这个问题的讨论:qiankun issue #1361