Javascript 如何在另一个vue应用程序中包含vue应用程序?

Javascript 如何在另一个vue应用程序中包含vue应用程序?,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我目前被要求生成将包含在不同客户网站中的小部件 比如说: 有两个约束: 禁止使用iframe 客户的网站可以用任何技术(PHP、React、ANgular、Vue.js、JQuery等)创建 由于请求的小部件应该是交互式的,所以我想使用javascript框架开发它(我考虑了Vue.js) 但是,我认为这可能会导致一些冲突(甚至破坏客户的网站),例如,如果客户的网站已经在使用另一个版本的Vue.js 我花了几个小时寻找和思考一个解决方案,但除了使用iframe之外,我什么也没发现 =>是否有办

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

比如说:

有两个约束:

  • 禁止使用iframe
  • 客户的网站可以用任何技术(PHP、React、ANgular、Vue.js、JQuery等)创建
  • 由于请求的小部件应该是交互式的,所以我想使用javascript框架开发它(我考虑了Vue.js)

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

    我花了几个小时寻找和思考一个解决方案,但除了使用iframe之外,我什么也没发现

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


    提前感谢您的帮助。

    我想,您最可能遇到的问题是版本不同(客户端使用Vue 2.5,而您使用的是2.6)

    我曾经在React和Vue中遇到过这种情况

    这可能是我如此热衷于将项目用作依赖项/小部件的实例的第一个原因


    如果你已经习惯了Vue,你应该很快就会有回家的感觉。值得注意的区别是,从技术上讲,它是一种语言,而不是一个框架,从dist bundle编译框架,因此您没有框架依赖性。

    您可以简单地使用JS解决。我已经完成了类似的任务,将我的Vue小部件附加到任何其他网站。以下是您可以执行的示例代码:

       const appendWidget = () => new Promise((resolve, reject) => {
           let e = document.createElement("div")
           e.setAttribute("id", "widgetToAppend");
           document.body.appendChild(e);
           let app = new Vue({
             el: "#widgetToAppend",
             template: `<div>YOUR COMPONENTS</div>`
           })
           resolve(app);
        })
    
    constappendwidget=()=>newpromise((解析,拒绝)=>{
    设e=document.createElement(“div”)
    e、 setAttribute(“id”、“widgetToAppend”);
    文件.正文.附件(e);
    让应用程序=新Vue({
    el:#widgetToAppend“,
    模板:`您的组件`
    })
    解析(app);
    })
    
    我现在的公司通常在客户的网页上提供嵌入式应用程序。 注意:尽管下面的示例是用
    .ts
    编写的,但在
    .js
    中几乎是相同的

    在测试了各种方法(Vue非常灵活)之后,下面是我们最终要做的:

    该方法受
    mapbox gl
    模型的启发,适用于Vue。
    基本原则很简单:将整个应用程序导出为干净的JS类(通过单个脚本导入),然后运行

    为此,我通常创建一个
    someClass.ts
    文件(该文件通常执行作业
    main.ts
    ),但导出一个类:

    从“Vue”导入Vue;
    从“/App.vue”导入应用程序;
    从“./store”导入存储;
    从“@/plugins/i18n”导入i18n;
    从“vue axios”导入VA;
    从“axios”导入axios;
    从“./store”导入存储;
    ...
    Vue.使用(VA、axios);
    Vue.config.productionTip=false;
    const实例=新的Vue({
    商店,
    i18n,
    组件:{App},
    数据:()=>({config:{}}),
    渲染:函数(createElement){
    返回createElement('应用'{
    道具:{config:this.config}
    });
    }
    });
    导出默认类SomeClass{
    构造函数(选择器:字符串,配置:SomeClassConfig){
    set(实例'config'{
    …配置,
    //id是可选的。但允许将应用程序的'id'动态设置为相同的'id'`
    //作为上下文页面占位符(由应用程序替换),以保持一致性
    //为此,您必须将`config.id`分配给应用程序的`mounted()中的`el``
    id:选择器。替换('#','')
    //或document.querySelector(selector).id | |'someClassApp'
    });
    实例。$mount(选择器);
    返回实例;
    }
    }
    //可选导出,用于整个应用程序的类型继承
    export const{$http,$t,$store}=Instance;
    
    注意:这一点非常清楚:上述导入都不是必需的(即:
    axios
    i18n
    ,等等…-这只是一个示例)。执行
    main.ts
    (或
    main.js
    )通常执行的任何操作。然后创建
    实例
    ,注入配置,从
    实例
    导出类和可能需要的任何命名导出

    上面的操作已经完成了(如果您使用下面指定的
    build
    命令构建它),但是您还必须调整
    main.ts
    以导入此类并在提供服务时呈现应用程序:

    从'@/SomeClass'导入SomeClass';
    导出默认的新SomeClass(“#devhook”{
    //配置对象
    });
    const app=document.querySelector(“#devhook”);
    如果(应用程序实例的HtmleElement){
    app.addEventListener('some-event',函数(e){
    if(自定义事件的实例){
    控制台日志(如详细信息);
    //您可以在此处测试上下文应用程序发出的事件。。。
    }
    });
    }
    
    public/index.html
    如下所示:

    new Someclass.default(selector, config);
    
    
    很抱歉,如果未启用JavaScript,则无法正常工作。请使其继续。
    
    生成命令是:

    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'
      }
    }
    
    configureWebpack: {
      externals: {
        lodash: 'window._'
      }
    }
    
    当您在上下文页面中导入类时,将允许您在不使用
    .default()
    的情况下初始化该类。如果没有上述webpack选项,您需要像这样初始化它:

    new Someclass.default(selector, config);
    
    其他一切都很标准

    现在,上下文页面只需要导入
    .umd.js
    ,用

    new SomeClass(selector, config)
    
    。。。并在渲染元素上添加一个或多个侦听器

    .umd.js
    导出可以从外部服务器提供,显然,可以从
    npm
    包导入

    如果单独加载它们(即:vue可能已经存在于上下文页面中)更有意义,则不必
    --内联css
    --内联vue
    。也,