将Vue应用安装到主Vue应用的容器中

hrp*_*xQ4 6 javascript vue.js

我想创建一个基本的Vue应用程序,该应用程序提供基本功能,例如登录,通过侧栏导航等。但是导航栏项必须是可互换的。我想创建代表这些导航栏项目的单独Vue应用程序。


基本思想:应该提供 一个REST API和一个基本容器(Vue应用程序),该容器能够在特定div元素中呈现其他Vue应用程序。这将允许其他人添加自己的前端应用程序,并在需要时使用该API。所以我只提供一些基本的应用程序。主要思想是为非常模块化的管理系统创建一个即插即用系统。我将为该自定义应用提供注册过程,以便API知道该应用及其基本URL,我的基本应用可以提取所有这些应用。

在此处输入图片说明


基本应用设置

所以我的基本应用程序为这些自定义应用程序提供了一条路线

{
  path: '/app/*',
  component: CustomAppContainer,
},
Run Code Online (Sandbox Code Playgroud)

并将呈现此视图

<template>
  <div id="customAppContainer">Render custom apps here</div>
</template>
Run Code Online (Sandbox Code Playgroud)

而我的导航栏可以提供链接/app/one来导航和渲染其中名为“ one”的应用customAppContainer


自定义应用设置

定义路线时,我必须设置base网址

export default new Router({
  base: '/one/',
  routes: [
    {
      path: '/',
      component: Home,
    },
  ],
});
Run Code Online (Sandbox Code Playgroud)

但是对于main.js,我不确定如何设置。我想我必须将其更新为

new Vue({
  router,
  render: h => h(CustomAppContainer),
}).$mount('#customAppContainer');
Run Code Online (Sandbox Code Playgroud)

但显然,此应用不知道CustomAppContainer#customAppContainer


此外,当我只有一些index.html文件并且想要将一个文件集成到另一个文件时,我正在考虑分发。那么,当用户希望通过/app/myCustomApp将定制应用程序安装到中来访问定制应用程序时,该如何部署基本应用程序customAppContainer呢?

一个类似的例子是Nextcloud

在开发新的Vue应用程序时,我可以将其作为独立的应用程序运行。但是对于生产而言,我想从dist文件夹中获取文件,并将它们放入apps目录中,并且在运行基本容器应用程序时,它在启动时就知道所有这些子应用程序。

如果您需要更多信息,请告诉我!

hrp*_*xQ4 5

我终于用以下方法让它工作了,也许这会对某人有所帮助。建议高度赞赏!


基础应用程序:

呈现所有子应用程序的基础应用程序有一个CustomAppContainer视图,它将子应用程序加载到一个 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>
Run Code Online (Sandbox Code Playgroud)

我进一步添加mode: 'history'路由器

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      component: Home
    },
    {
      path: '/apps/*',
      component: CustomAppContainer,
    }
  ]
})
Run Code Online (Sandbox Code Playgroud)

我将该应用程序的构建文件放入名为base的文件夹中的生产目录中


文件服务器:

我创建了一个静态 Express 文件服务器,它始终为基础应用程序的index.html文件提供服务。但是我也可以请求子应用程序的index.html文件。

const express = require('express');
const path = require('path');
const fs = require('fs');
const cors = require('cors');
const app = express();
const router = express.Router();

app.use(cors());

app.use(express.static(path.resolve(__dirname, '../base')));

fs.readdirSync(path.resolve(__dirname, '../apps')).forEach(appName => {
    app.use(express.static(path.resolve(__dirname, `../apps/${appName}`)));
});

router.get('/subApps/:appName', function(req, res) {
    res.sendFile(path.resolve(__dirname, `../apps/${req.params.appName}/index.html`));
});

router.get('*', function(req, res) {
    res.sendFile(path.resolve(__dirname, '../base/index.html'));
});

app.use('/', router);

app.listen(3000, function() {
    console.log('Fileserver listening on port 3000');
});
Run Code Online (Sandbox Code Playgroud)

自定义应用程序:

创建自定义应用程序时,我所要做的就是扩展路由器配置

export default new Router({
    base: '/my-first-custom-app/',
    mode: 'history',
    routes: [
        {
            path: '/',
            component: PageOne,
        },
        {
            path: '/two',
            component: PageTwo,
        },
    ],
});
Run Code Online (Sandbox Code Playgroud)

和重命名#appID到#customApp的index.htmlmain.jsApp.vue

此外,我将该子应用程序的构建文件放入名为apps的文件夹中的生产目录中。


这允许我创建多个应用程序并将它们呈现到我的主应用程序容器的 div 容器中。子应用程序本身不必是 Vue 应用程序。我也可以使用 Jquery、Angular 或 React 创建新应用程序,甚至只是一个普通的 .html 文件。


Jav*_*Dev 3

1

维尤不知道CustomAppContainer

尝试添加import CustomAppContainer from "path/to/CustomAppContainer.vue"
它必须在 .vue 文件中。


2

维尤不知道#customAppContainer

是的,该选择器必须位于index.html. 你的在CustomAppContainer. 尝试添加index.html(通常在 /public 文件夹中)类似的内容<div id="#app"></div>并替换.$mount('#customAppContainer');.$mount('#app');


3

Vue 路由器需要<router-view>标签。所以,尝试这个标记:

<!-- In template is all page -->
<template>
  <!-- Some stuff as navigation... -->
  <nav>
    <!-- Router links - renders as "a" element -->
    <router-link to="/one">To /one</router-link>
    <!-- Or use standard tags - they're also good -->
    <a href="/two">To /two</a>
  </nav>
  <!-- In this component would be component chosen in router (Home.vue) -->
  <router-view/>
</template>
Run Code Online (Sandbox Code Playgroud)

4

Router.js 需要导入:

import Home from "path/to/the/Home.vue"
export default new Router({
  base: '/one/',
  routes: [
    {
      path: '/',
      component: Home,
    },
  ],
});
Run Code Online (Sandbox Code Playgroud)

一切都很好?