javascript - 在嵌入式 Vue 应用程序中操作浏览器 URL
问题描述
我目前将 Vue 应用程序渲染为 Vue 应用程序。我通过将子应用的 index.html 文件嵌入到主应用的 div 容器中来实现这一点。
<template>
<div id="customAppContainer"></div>
</template>
<script>
export default {
mounted() {
this.updateCustomAppContainer();
},
methods: {
updateCustomAppContainer() {
const fullRoute = this.$router.currentRoute.fullPath;
const routeSegments = fullRoute.split("/");
const appsIndex = routeSegments.indexOf("apps");
const appKey = routeSegments[appsIndex + 1];
document.getElementById(
"customAppContainer"
).innerHTML = `<object style="width: 100%; height:100%;" data="http://localhost:3000/subApps/${appKey}"></object>`;
}
},
watch: {
$route(to, from) {
this.updateCustomAppContainer();
}
}
};
</script>
如果您想了解更多相关信息,请查看此处
和我自己对这个问题的回答
https://stackoverflow.com/a/58265830/9945420
object
我在标签内呈现的子应用程序customAppContainer
有它自己的路由,基本路由将是
export default new Router({
base: '/my-first-custom-app/',
mode: 'history',
routes: [
{
path: '/',
component: PageOne,
},
{
path: '/two',
component: PageTwo,
},
],
});
我可以浏览我的子应用程序并记录当前的 url
<script>
export default {
created() {
console.log(this.$router.currentRoute.fullPath);
}
};
</script>
在第一条路线上我得到/
了,在第二条路线上我得到了/two
。这是对的。但是在浏览子应用程序时,浏览器 URL 永远不会改变。调用localhost:3000/apps/my-first-custom-app/two
文件服务器时index.html
,无法转发到/two
.
是否可以转发到正确的路线?并在浏览子应用程序时操纵浏览器 URL?
更新:
我试图删除对象标签,因为它们似乎创建了一个黑盒。我在这里找到了另一种方法
https://stackoverflow.com/a/55209788/9945420
更新的代码应该是
<template>
<div id="customAppContainer"></div>
</template>
<script>
export default {
async mounted() {
await this.updateCustomAppContainer();
},
methods: {
async updateCustomAppContainer() {
const fullRoute = this.$router.currentRoute.fullPath;
const routeSegments = fullRoute.split("/");
const appsIndex = routeSegments.indexOf("apps");
const appKey = routeSegments[appsIndex + 1];
// document.getElementById(
// "customAppContainer"
// ).innerHTML = `<object style="width: 100%; height:100%;" data="http://localhost:3000/subApps/${appKey}"></object>`;
const response = await fetch(`http://localhost:3000/subApps/${appKey}`);
const htmlContent = await response.text();
document.getElementById("customAppContainer").innerHTML = htmlContent;
}
},
watch: {
async $route(to, from) {
await this.updateCustomAppContainer();
}
}
};
</script>
此代码适用于纯 HTML 文件(无 Vue 应用程序),但当我想嵌入分布式 Vue 应用程序时,此应用程序不会呈现。
极简再现
我创建了一个用于复制的简约存储库。
https://github.com/byteCrunsher/temp-reproduction
开发目录包含静态文件服务器、应该渲染 Vue 应用程序的基本 Vue 应用程序和应用程序本身。请记住,第一个应用程序是 Vue 应用程序,第二个应用程序只是一个基本的 HTML 文件。
生产目录包含文件服务器、分布式 Vue 应用程序和 html 文件。只需从生产目录运行静态文件服务器,然后转到http://localhost:3000
您应该看到我当前的工作。
更新
当我使用 vue 指令v-html
并将响应存储到数据属性 ( https://hatebin.com/casjdcehrj ) 时,我会从服务器获得此响应
这是我使用时得到的内容await response.text();
解决方案
我只是自己解决了这个问题。我采用了 IFrame / object 标签方式
document.getElementById(
"customAppContainer"
).innerHTML = `<object style="width: 100%; height:100%;" data="http://localhost:3000/subApps/${appKey}"></object>`;
这种方式的缺点是将嵌入式应用程序与主应用程序隔离开来。但是可以通过 localStorage 进行通信。subApp 扩展了它的 router.js 文件
router.afterEach((to, from) => {
localStorage.subAppRouteUpdate = to.path;
});
每当我浏览该嵌入式应用程序时都会触发此事件,并将更新的 url 存储到 localStorage。基础应用程序可以监听该存储更改。在 App.vue 中,它添加了一个事件监听器并将 subApp url 附加到浏览器 url
<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>
使用这种方法,我目前能够浏览我的容器化子应用程序,并且仍然可以更新浏览器 url。
推荐阅读
- javascript - Strapi:如何通过 id 获取一个条目
- thymeleaf - Thymeleaf:如何保持对多重迭代器的计数
- reactjs - 在 useEffect 中监听套接字事件没有得到最新消息
- python - 我如何将base64作为img保存到DB python烧瓶
- javascript - 带有 vue 2.16.12 的 webpack 模块联合和 single-spa-vue 不起作用
- android - Flutter abiFilters
- c# - 除了少数之外,所有属性都不是空的
- python - Pytorch:创建一个大于批次中每个 2D 张量的第 n 个分位数的掩码
- qt - C++ QPixmap from 图像分割错误
- reactjs - react-markdown - 斜杠后加粗