gpt4 book ai didi

javascript - 如何将 vue 应用程序包含在另一个 vue 应用程序中?

转载 作者:行者123 更新时间:2023-12-03 23:34:33 50 4
gpt4 key购买 nike

我目前被要求生成将包含在不同客户网站中的小部件。

让我们这样说:

exemple

有2个约束:

  • 禁止使用 iframe
  • 客户网站可以使用任何技术(PHP、React、ANGular、Vue.js、JQuery...)

  • 由于请求的小部件应该是交互式的,我想使用 javascript 框架开发它(我想到了 Vue.js)。

    但是,我认为这可能会导致一些冲突(甚至破坏客户的网站),例如如果客户的网站已经在使用另一个版本的 Vue.js。

    我花了几个小时寻找和思考解决方案,但期望使用 iframe 我没有找到任何东西......

    => 有没有办法将 Vue.js 应用程序包含在另一个 Vue.js 应用程序(或 React、Angular 等)中?

    在此先感谢您的帮助。

    最佳答案

    重要编辑 :
    自从我写了这个答案后,我发现了一种更简单的方法,可以将整个项目包装为单个 .js文件,documented here .
    如果您需要更多地控制应用程序的实例化时间以及它是否应该包含 Vue,这是原始答案(不是声称它更好 - 我只是在没有任何替代方案的时候写了它,并且它有效):

    原答案 :
    我目前的公司通常在我们客户的网页中提供嵌入式应用程序。
    注意:虽然下面的例子是写在 .ts ,在 .js 中几乎相同.
    在测试了各种方法(Vue 非常灵活)之后,我们最终做了以下工作:
    该方法的灵感来自 mapbox-gl的模型,适配 Vue。
    基本原理很简单:将整个应用导出为干净的 JS 类(通过单个脚本导入)并运行

    new SomeClass(selector, config);
    为此,我通常创建一个 someClass.ts文件(通常会执行 main.ts 的工作),但会导出一个类:
    import Vue from 'vue';
    import App from './App.vue';
    import store from './store';
    import i18n from '@/plugins/i18n';
    import VA from 'vue-axios';
    import axios from 'axios';
    import store from './store';
    ...

    Vue.use(VA, axios);
    Vue.config.productionTip = false;

    const Instance = new Vue({
    store,
    i18n,
    components: { App },
    data: () => ({ config: {} }),
    render: function(createElement) {
    return createElement('app', {
    props: { config: this.config }
    });
    }
    });

    export default class SomeClass {
    constructor(selector: string, config: SomeClassConfig) {
    Vue.set(Instance, 'config', {
    ...config,
    // id is optional. but allows setting the app's `id` dynamically to same `id`
    // as the context page placeholder (which app replaces), for consistency
    // for this, you have to assign `config.id` to App's `$el` in its `mounted()`
    id: selector.replace('#', '')
    // or document.querySelector(selector).id || 'someClassApp'
    });
    Instance.$mount(selector);
    return Instance;
    }
    }

    // optional exports, used for type inheritance throughout the app
    export const { $http, $t, $store } = Instance;

    注:让这一切变得清晰: 上述进口是必要的(即: axiosi18n 等...... - 这只是一个例子)。做任何你的 main.ts (或 main.js )通常是这样做的。然后创建 Instance ,注入(inject)配置,从 Instance 导出你可能需要的类和任何命名的导出.
    上面已经完成了工作(如果你使用下面指定的 build 命令构建它),但你还必须适应 main.ts导入此类并在服务时呈现应用程序:
    import SomeClass from '@/someClass';

    export default new SomeClass('#devhook', {
    // config object
    });

    const app = document.querySelector('#devhook');
    if (app instanceof HTMLElement) {
    app.addEventListener('some-event', function(e) {
    if (e instanceof CustomEvent) {
    console.log(e.detail);
    // you can test events emitted for context app here...
    }
    });
    }

    public/index.html看起来像这样:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="./favicon.ico">
    <!-- VueJS -->
    <script src="https://cdn.jsdelivr.net/npm/vue@latest/dist/vue.min.js"></script>
    <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
    <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="devhook"></div>
    <!-- built files will be auto injected -->
    </body>
    </html>

    构建命令是:
    vue-cli-service build --target lib --name SomeClass --inline-css --inline-vue src/someClass.ts
    请注意,我们正在导出 src/someClass.ts .您最终会得到一个名为 SomeClass.umd.js 的文件。 .
    此外,将此设置添加到 config.vue.js :
    configureWebpack: {
    output: {
    libraryExport: 'default'
    }
    }
    将使您能够在没有 .default() 的情况下初始化类(class)当您在上下文页面中导入它时。如果没有上面的 webpack 选项,你需要像这样初始化它:
    new Someclass.default(selector, config);
    其他一切都很标准。
    现在上下文页面只需要导入 .umd.js , 实例化应用程序
    new SomeClass(selector, config)
    ...并在呈现的元素上添加一个或多个监听器。 .umd.js可以从外部服务器提供导出服务,并且显然可以从 npm 导入。包裹。
    您不必 --inline-css--inline-vue如果单独加载它们更有意义(即:Vue 可能已经存在于上下文页面中)。此外,我经常依赖上下文页面中已经存在的库(您希望尽可能多地重用库),使用 vue.config.js :
    configureWebpack: {
    externals: {
    lodash: 'window._'
    }
    }
    执行此操作时,请记住在 public/index.html 中添加指向 lodash/jquery/whatever cdn 的脚本,所以它在服务/开发时被加载,就像在上下文页面中一样。
    最后, demo.html (用于展示产品构建),如下所示:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Some Class App Demo</title>
    <link rel="shortcut icon" href="./favicon.ico"/>

    <!-- also works when served from a different domain -->
    <script src="./SomeClass.umd.min.js"></script>
    <link rel="stylesheet" href="./SomeClass.css">

    </head>
    <body>
    <div id="SomeClassApp"></div>

    <script>
    const config = {
    // whatever
    };
    const app = new SomeClass('#SomeClassApp', config);

    if (app.$el instanceof HTMLElement) {
    app.$el.addEventListener('some-event', function(e) {
    if (e instanceof CustomEvent) {
    console.log(e.detail);
    }
    });
    }
    </script>
    </body>

    当然,您必须在应用程序的脚本 ( ./SomeClass.umd.min.js ) 之前添加所有外部组件,如果您使用过的话。不要 defer他们。该应用程序期望它们加载到 window到它开始的时候。
    至于冲突,你不应该有。 Vue 在未成年人之间高度兼容,因此您可以简单地使用上下文页面的 Vue(而不是内联它)。此外,Vue 2 语法应该与 Vue 3 完全兼容(例如,您可以使用 Vue 3 运行 Vue 2 应用程序而无需对其进行任何更改 - 我们将拭目以待)。

    关于javascript - 如何将 vue 应用程序包含在另一个 vue 应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61899394/

    50 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com