【发布时间】:2020-02-04 17:05:51
【问题描述】:
我目前将 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>
如果你想了解更多,请看这里
mount Vue apps into container of main Vue app
以及我自己对这个问题的回答
https://stackoverflow.com/a/58265830/9945420
在customAppContainer 的object 标签内呈现的我的子应用有自己的路由,基本路由是
export default new Router({
base: '/my-first-custom-app/',
mode: 'history',
routes: [
{
path: '/',
component: PageOne,
},
{
path: '/two',
component: PageTwo,
},
],
});
我可以浏览我的子应用并记录当前网址
<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();时得到的内容
【问题讨论】:
-
所以你有一个(单个)vue 应用程序并且你想嵌入(远程获取)html?
<container id-".." v-html="dataHTML">有什么问题,您将获取的数据放入data.dataHTML或类似的东西? -
非常感谢您的回复。我用这段代码hatebin.com/casjdcehrj 试过了,但仍然没有渲染子应用程序。仍然......纯 HTML 文件被渲染。
-
subApp的内容是什么 - 你真的得到一些 text/data/html 吗?您可能会遇到 CORS 拒绝, -
嘿,这是我从服务器cdn.discordapp.com/attachments/165027329981153280/… 得到的响应,当我使用
await response.text()将其转换为文本时,我得到了cdn.discordapp.com/attachments/165027329981153280/… -
@hrp8sfHxQ4 所以你真的想在 div 中嵌入一个完整的 html 文档? - 因为那是无效的 html,你可以使用 iframe(with src-attr) 代替。另一方面,我不确定您的
app1 > div > remote-html(app2)是否是正确的方法。您能否明确您真正想要解决的问题,以及为什么常规 async-components(in app1) 不够?您想嵌入您无法控制的应用程序吗?子应用与主应用有何不同,为什么要分开?
标签: javascript html vue.js