mustard-app
Version:
个人前端微应用建设中。。。
132 lines (117 loc) • 4.47 kB
text/typescript
import App from './app';
import { changeDomPropety } from './proxy/proxyDocument';
import { appIsExist, getAppFromInstance }from './global';
import { AppName, IAppStatusCN, MainMustardApp, MustardName, MustardURL } from './typings';
import { addEventListenerUrl, checkUrl } from './check/urlCheck';
import { changeHistoryPropety } from './proxy/proxyHistory';
import { EventCenterBaseApp } from './communication';
import { isFunction, isIAppStatusKey } from './utils/tools';
import { nextTick } from './utils';
const eventCenter = new EventCenterBaseApp();
const rawSetAttribute = HTMLElement.prototype.setAttribute;
const rawAddEventListener = HTMLElement.prototype.addEventListener;
const rawRemoveEventListener = HTMLElement.prototype.removeEventListener;
type AddEventListenerParams = Parameters<typeof rawAddEventListener>
type EventListenerType = 'dataChange' | IAppStatusCN | keyof HTMLElementEventMap;
type EventListenerListener = AddEventListenerParams[1];
type EventListenerOptions = AddEventListenerParams[2];
export class MustardApp extends HTMLElement {
url:MustardURL = ''; // 子应用资源地址
name:MustardName = ''; // 子应用标识
// keepAlive:boolean = true; // dom移除是否保活
checkUrlStop:()=>void; // URL 校验关闭
static get observedAttributes () {
return ['name', 'url'];
}
constructor () {
super();
}
// 组件刷新
reload () {
const app = getAppFromInstance(this.name);
if(app) {
app.reload();
}
}
// 子应用添加至页面
connectedCallback () {
if(!appIsExist(this.name) && this.url) {
nextTick(() => {
new App({
url: this.url,
name: this.name,
container: this
});
});
}
// 开启URL校验
this.checkUrlStop = addEventListenerUrl(()=>{
checkUrl(this.name);
});
}
// 子应用从页面中移除
disconnectedCallback () {
// 关闭URL校验
this.checkUrlStop?.();
// getAppFromInstance(this.name)?.unmount(true);
}
// 子应用移动至新页面。
adoptedCallback () {}
/**
* 属性变化
* @param name 属性名
* @param oldValue 属性旧值
* @param newValue 属性新值
*/
attributeChangedCallback (name, oldValue, newValue) {
if(!this.name && name === 'name') {
if(newValue === MainMustardApp) {
throw new Error('子应用标识非法');
}
if(appIsExist(name)) {
throw new Error(`子应用标识已存在: ${name}`);
}else{
this.name = newValue;
}
}else if(!this.url && name === 'url') {
this.url = newValue;
}
}
setAttribute (key:string, value:unknown) {
if (/^mustard-app/i.test(this.tagName) && key === 'data') {
// 发送数据
eventCenter.dispatch(this.name, value);
} else {
rawSetAttribute.call(this, key, value);
}
}
addEventListener (type: EventListenerType, listener: EventListenerListener, options?: EventListenerOptions): void {
if(isFunction(listener)) {
if(type === 'dataChange') {
eventCenter.onData(this.name, listener);
}else if(isIAppStatusKey(type)) {
eventCenter.onLife(this.name, type, listener);
}else{
rawAddEventListener.call(this, type, listener, options);
}
}
}
removeEventListener (type: EventListenerType, listener: EventListenerListener, options?: EventListenerOptions): void {
if(isFunction(listener)) {
if(type === 'dataChange') {
eventCenter.offData(this.name, listener);
}else if(isIAppStatusKey(type)) {
eventCenter.offLife(this.name, type, listener);
}else{
rawRemoveEventListener.call(this, type, listener, options);
}
}
}
}
export function defineMustardAppElement () {
if(!customElements.get(AppName)) {
changeDomPropety();
changeHistoryPropety();
customElements.define(AppName, MustardApp);
}
}