我目前正在容器/主 Vue 应用程序的对象标签(iframe 也可以工作)内渲染 Vue 应用程序。首先,我设置一个文件服务器,为该容器或请求的子应用程序提供服务,以在 div 内呈现。
为了简单起见,我将仅显示 Node/Express 服务器所需的路由
// serve the sub-app on demand
router.get('/subApps/:appName', function(req, res) {
res.sendFile(path.resolve(__dirname, `../apps/${req.params.appName}/index.html`);
});
// always render the app container if no sub-app was requested
router.get('*', function(req, res) {
res.sendFile(path.resolve(__dirname, '../base/index.html'));
});
我的应用程序容器/主 Vue 应用程序位于渲染的视图文件内/apps/:appName
,请求该子应用程序并将其包装到对象标签中
document.getElementById("customAppContainer").innerHTML = `<object style="width: 100%; height:100%;" data="http://localhost:3000/subApps/${appKey}"></object>`;
这种方法工作正常,但渲染的子应用程序使用启动 urlhttp://localhost:3000/subApps/app-one
虽然它应该使用 urlhttp://localhost:3000/apps/app-one
。当子应用程序加载路由器实例时,我必须将启动 url 从 iframe url 更改为浏览器 url(父级)。
我想解决这个问题history.replaceState
const router = new Router({ ... });
router.afterEach((to, from) => {
localStorage.subAppRouteUpdate = to.path;
});
if (window.location !== window.parent.location) {
const browserUrl = top.location.href;
history.replaceState(null, null, browserUrl);
}
export default router;
我为什么要这样做?这App.vue主应用程序的应将子应用程序路由附加到浏览器 URL。通过这种方法,可以在子应用程序内部导航时更新浏览器 URL。我通过将子应用程序 URL 存储到本地存储并侦听主应用程序端的本地存储更改来实现此目的。所以App.vue文件使用此代码
<script>
export default {
created() {
window.addEventListener("storage", () => {
const fullRoute = this.$router.currentRoute.fullPath;
const routeSegments = fullRoute.split("/");
const appsIndex = routeSegments.indexOf("apps");
const newBaseUrlSegments = routeSegments.slice(0, appsIndex + 2);
const newBaseUrl = newBaseUrlSegments.join("/");
const subAppRoute = localStorage.subAppRouteUpdate;
const updatedUrl = newBaseUrl.concat(subAppRoute);
history.replaceState(null, null, updatedUrl);
});
}
};
</script>
使用 IFrame 时启用路由。它几乎可以工作,这就是我得到的
不幸的是,当打电话时/
浏览器 URL 更新为子应用程序的
http://localhost:3000/apps/app-one/apps/app-one http://localhost:3000/apps/app-one/apps/app-one
虽然我在期待
http://localhost:3000/apps/app-one/ http://localhost:3000/apps/app-one/
再生产:
我创建了一个存储库 https://github.com/byteCrunsher/reproduction用于复制/测试。有人知道可能出了什么问题或如何修复该网址更新吗?
Update:
我认为发生错误是因为路由器.js我正在触发此代码的子应用程序
if (window.location !== window.parent.location) {
const browserUrl = top.location.href;
history.replaceState(null, null, browserUrl);
}
router.afterEach((to, from) => {
console.log({ urlToAppend: to.path });
localStorage.subAppRouteUpdate = to.path;
});
ReplaceState 函数将更新 IFrame url/subApps/app-one
到正确的浏览器网址/apps/app-one
。不幸的是,这将触发 afterEach 事件并且to.path
结果是/apps/app-one
虽然应该是/
.
如果网址是/apps/app-one/users/create
每个事件之后应该触发/users/create
当然。
但我不知道如何修复这个第一个触发的事件。