开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情
本文主要介绍CustomEvent及其在微前端应用间通信中的应用。
1 CustomEvent
MDN中对CustomEvent的介绍如下:
CustomEvent 事件是由程序创建的,可以有任意自定义功能的事件。
可以利用构造函数CustomEvent()来创建自定义功能的事件。
栗子如下:
<script type="text/javascript">
/* 创建一个事件对象,名字为newEvent,类型为build */
var newEvent = new CustomEvent('build', { bubbles:true,cancelable:true,composed:true });
/* 给这个事件对象创建一个属性并赋值,这里绑定的事件要和我们创建的事件类型相同,不然无法触发 */
newEvent.name = "新的事件!";
/* 将自定义事件绑定在document对象上 */
document.addEventListener("build",function(){
alert("你触发了使用CustomEvent创建的自定义事件!" + newEvent.name);
},false)
/* 触发自定义事件 */
document.dispatchEvent(newEvent);
</script>
在caniuse.com上搜索CustomEvent发现
在IE中可做如下polyfill
/**
* CustomEvent constructor polyfill for IE
*/
(function () {
if (typeof window.CustomEvent === 'function') {
// 如果不是IE
return false;
}
var CustomEvent = function (event, params) {
params = params || {
bubbles: false,
cancelable: false,
detail: undefined
};
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
};
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
2 CustomEvent的应用
CustomEvent可应用于微前端中应用间的通信。为进行实操,从GitHub上clone了一份qiankun(github.com/umijs/qiank…)的源码。主要做了如下改造:
examples/main/multiple.js
import { loadMicroApp } from '../../es';
let app;
document.addEventListener("qiankun", function(){
// alert("你触发了使用CustomEvent创建的自定义事件!" + qiankunEvent.name);
alert("你触发了使用CustomEvent创建的自定义事件!");
},false)
function mount() {
app = loadMicroApp(
{ name: 'react15', entry: '//localhost:7102', container: '#react15' },
{ sandbox: { experimentalStyleIsolation: true } },
);
}
function unmount() {
app.unmount();
}
document.querySelector('#mount').addEventListener('click', mount);
document.querySelector('#unmount').addEventListener('click', unmount);
loadMicroApp({ name: 'vue', entry: '//localhost:7101', container: '#vue' });
examples/vue/src/views/About.vue
<template>
<div class="about">
<h1>This is about page</h1>
<el-button type="primary" @click="onClick">Click Main</el-button>
<el-button type="primary" @click="onCall">Call React15</el-button>
<p>{{message}}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'vue'
}
},
methods: {
onClick(){
document.dispatchEvent(new CustomEvent('qiankun', { bubbles:true,cancelable:true,composed:true }))
},
onCall(){
document.dispatchEvent(new CustomEvent('qiankun:react15', { bubbles:true,cancelable:true,composed:true }))
}
},
mounted () {
const _this = this
document.addEventListener("qiankun:vue", function(){
// alert("你触发了使用CustomEvent创建的自定义事件!" + qiankunEvent.name);
alert("你触发了使用CustomEvent创建的自定义事件!vue");
_this.message = 'React15 call Vue'
},false)
},
}
</script>
<style scoped>
.about {
color: #7265e6;
}
</style>
examples/react15/App.jsx
import React, { version as reactVersion } from 'react';
import { version as antdVersion, Button } from 'antd';
import Logo from './components/Logo'
import HelloModal from './components/HelloModal'
// import { message } from 'vfile/node_modules/vfile-message';
export default class App extends React.Component {
constructor(props){
super(props)
this.state = {
message: 'React15'
}
this.setCall = message => {
console.log('message', message)
document.dispatchEvent(new CustomEvent('qiankun:vue', { bubbles:true,cancelable:true,composed:true }))
}
}
componentDidMount(){
const _this = this
document.addEventListener("qiankun:react15", function(){
// alert("你触发了使用CustomEvent创建的自定义事件!" + qiankunEvent.name);
alert("你触发了使用CustomEvent创建的自定义事件!React15");
_this.setState({
message: 'Vue call React15'
})
},false)
}
render() {
return (
<div className="react15-main">
<Logo />
<p className="react15-lib">
React version: {reactVersion}, AntD version: {antdVersion}
</p>
<HelloModal />
<p>{this.state.message}</p>
<Button onClick={() => this.setCall('call vue')}>Call Vue</Button>
</div>
);
}
}
启动跟路径下package.json中的
examples:start-multiple可以在浏览器中看到如下页面。
通过上述实践可知,基于CustomEvent的微前端应用通信机制具有浏览器原生支持、应用间弱耦合等优点,也具有全局命名冲突、缺乏规范等缺点。
3 总结
本文主要介绍了CustomEvent及其在微前端应用间通信中的应用。CustomEvent是浏览器原生支持的API,但存在兼容性问题,可以polyfill。CustomEvent可以应用于微前端应用间的通信。
参考文献
[1] www.cnblogs.com/cwsb/p/1038…
[2] developer.mozilla.org/zh-CN/docs/…
[3] developer.mozilla.org/zh-CN/docs/…
[4] www.mifengjc.com/api/CustomE…
[5] www.jianshu.com/p/1cf1c80c0…