Dav*_*SEY 4 javascript vue.js vuejs2
我目前被要求生成将包含在不同客户网站中的小部件。
让我们这样说:
有2个约束:
由于请求的小部件应该是交互式的,我想使用 javascript 框架来开发它(我想到了 Vue.js)。
但是,我认为这可能会导致一些冲突(甚至破坏客户的网站),例如,如果客户的网站已经在使用另一个版本的 Vue.js。
我花了几个小时寻找和思考解决方案,但期望使用 iframe 我没有找到任何东西......
=> 有没有办法将 Vue.js 应用程序包含在另一个 Vue.js 应用程序(或 React、Angular 等)中?
在此先感谢您的帮助。
And*_*hiu 14
我现在的公司通常在我们客户的网页中提供嵌入式应用程序。注意:虽然下面的例子是用 编写的.ts,但它在.js.
在测试了各种方法(Vue 非常灵活)之后,我们最终做了以下事情:
该方法受mapbox-gl的模型启发,适用于 Vue。
基本原则很简单:将整个应用程序导出为一个干净的 JS 类(通过单个脚本导入)并运行
new SomeClass(selector, config);
Run Code Online (Sandbox Code Playgroud)
为此,我通常创建一个 someClass.ts文件(main.ts通常会完成这项工作),但会导出一个类:
new SomeClass(selector, config);
Run Code Online (Sandbox Code Playgroud)
注:进行此晶莹剔透:无以上的进口是必要的(即:axios,i18n,等等-这只是一个例子)。做你main.ts(或main.js)通常在做的事情。然后创建Instance、注入配置、导出类以及您可能需要的任何命名导出Instance。
以上已经完成了工作(如果您使用build下面指定的命令构建它),但您还必须适应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;
Run Code Online (Sandbox Code Playgroud)
而且public/index.html是这样的:
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...
}
});
}
Run Code Online (Sandbox Code Playgroud)
构建命令是:
vue-cli-service build --target lib --name SomeClass --inline-css --inline-vue src/someClass.ts
Run Code Online (Sandbox Code Playgroud)
请注意,我们正在导出src/someClass.ts. 你最终会得到一个名为SomeClass.umd.js.
此外,将此设置添加到config.vue.js:
configureWebpack: {
output: {
libraryExport: 'default'
}
}
Run Code Online (Sandbox Code Playgroud)
将使您无需.default()在上下文页面中导入类即可初始化该类。如果没有上面的 webpack 选项,你需要像这样初始化它:
new Someclass.default(selector, config);
Run Code Online (Sandbox Code Playgroud)
其他一切都很标准。
现在上下文页面只需要导入.umd.js,实例化应用程序
new SomeClass(selector, config)
Run Code Online (Sandbox Code Playgroud)
...并在渲染元素上添加一个或多个侦听器。
该.umd.js出口可以从外部服务器提供服务,很明显,可以从进口npm包。
您不必--inline-css,--inline-vue如果单独加载它们更有意义(即:Vue 可能已经存在于上下文页面中)。此外,我经常依赖上下文页面中已经存在的库(您希望重用尽可能多的库),使用vue.config.js:
configureWebpack: {
externals: {
lodash: 'window._'
}
}
Run Code Online (Sandbox Code Playgroud)
执行此操作时,请记住添加一个指向 lodash/jquery/whatever cdn in 的脚本public/index.html,以便在服务/开发时加载它,就像在上下文页面中一样。
最后,demo.html(用于展示 prod 构建)看起来像这样:
<!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>
Run Code Online (Sandbox Code Playgroud)
当然,您必须在应用程序脚本 ( ./SomeClass.umd.min.js)之前向其中添加所有外部组件(如果您使用了任何外部组件)。不要defer他们。该应用程序希望在window它启动时加载它们。
至于冲突,你不应该有任何冲突。Vue 在未成年人之间高度兼容,因此您可以简单地使用上下文页面的 Vue(而不是内联它)。此外,Vue 2 语法应该与 Vue 3 完全兼容(例如,您可以使用 Vue 3 运行 Vue 2 应用程序,而无需对其进行任何更改 - 我们将看到)。
| 归档时间: |
|
| 查看次数: |
2604 次 |
| 最近记录: |