mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-18 07:12:49 +00:00
perf: 优化应用参数
This commit is contained in:
parent
4cc0c85a6c
commit
937e7ba154
@ -66,34 +66,71 @@ export default {
|
|||||||
return {
|
return {
|
||||||
src: this.url,
|
src: this.url,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
onBeforeClose: {},
|
hasMounted: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.injectMicroApp()
|
this.pendingBeforeCloses = new Map();
|
||||||
window.addEventListener('message', this.handleMessage.bind(this))
|
this.pendingFunctionCalls = new Map();
|
||||||
this.$refs.iframe.addEventListener('load', this.handleLoad.bind(this))
|
|
||||||
this.$refs.iframe.addEventListener('error', this.handleError.bind(this))
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
||||||
|
this.boundHandleLoad = this.handleLoad.bind(this);
|
||||||
|
this.boundHandleError = this.handleError.bind(this);
|
||||||
|
|
||||||
|
this.injectMicroApp();
|
||||||
|
window.addEventListener('message', this.boundHandleMessage);
|
||||||
|
this.$refs.iframe.addEventListener('load', this.boundHandleLoad);
|
||||||
|
this.$refs.iframe.addEventListener('error', this.boundHandleError);
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.cleanupMicroApp()
|
this.cleanupMicroApp();
|
||||||
window.removeEventListener('message', this.handleMessage.bind(this))
|
|
||||||
this.$refs.iframe.removeEventListener('load', this.handleLoad.bind(this))
|
// 正确移除事件监听器
|
||||||
this.$refs.iframe.removeEventListener('error', this.handleError.bind(this))
|
if (this.boundHandleMessage) {
|
||||||
|
window.removeEventListener('message', this.boundHandleMessage);
|
||||||
|
}
|
||||||
|
if (this.boundHandleLoad) {
|
||||||
|
this.$refs.iframe.removeEventListener('load', this.boundHandleLoad);
|
||||||
|
}
|
||||||
|
if (this.boundHandleError) {
|
||||||
|
this.$refs.iframe.removeEventListener('error', this.boundHandleError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理待处理的函数调用
|
||||||
|
if (this.pendingFunctionCalls) {
|
||||||
|
this.pendingFunctionCalls.forEach(pending => {
|
||||||
|
clearTimeout(pending.timeout);
|
||||||
|
pending.reject(new Error('Component destroyed'));
|
||||||
|
});
|
||||||
|
this.pendingFunctionCalls.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理待处理的关闭回调
|
||||||
|
if (this.pendingBeforeCloses) {
|
||||||
|
this.pendingBeforeCloses.forEach(resolve => {
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
|
this.pendingBeforeCloses.clear();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// 处理 iframe 加载完成
|
// 处理 iframe 加载完成
|
||||||
handleLoad() {
|
handleLoad() {
|
||||||
|
// 总是执行注入
|
||||||
this.injectMicroApp()
|
this.injectMicroApp()
|
||||||
|
|
||||||
|
// 只触发一次 mounted 事件
|
||||||
|
if (!this.hasMounted) {
|
||||||
|
this.hasMounted = true
|
||||||
this.$emit('mounted', {
|
this.$emit('mounted', {
|
||||||
detail: {
|
detail: {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理 iframe 加载错误
|
// 处理 iframe 加载错误
|
||||||
@ -114,15 +151,19 @@ export default {
|
|||||||
const {type, message} = e.data;
|
const {type, message} = e.data;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'MICRO_APP_READY':
|
case 'MICRO_APP_READY':
|
||||||
this.handleMessageOfReady(message);
|
this.handleMessageOfReady(this.handleMessageEnsureJson(message));
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'MICRO_APP_METHOD':
|
case 'MICRO_APP_METHOD':
|
||||||
this.handleMessageOfMethod(message)
|
this.handleMessageOfMethod(this.handleMessageEnsureJson(message))
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'MICRO_APP_FUNCTION_RESULT':
|
||||||
|
this.handleMessageOfFunctionResult(this.handleMessageEnsureJson(message))
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'MICRO_APP_BEFORE_CLOSE':
|
case 'MICRO_APP_BEFORE_CLOSE':
|
||||||
this.handleMessageOfBeforeClose(message)
|
this.handleMessageOfBeforeClose(this.handleMessageEnsureJson(message))
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -130,12 +171,17 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 确保消息是 JSON 格式
|
||||||
|
handleMessageEnsureJson(message) {
|
||||||
|
return $A.isJson(message) ? message : {}
|
||||||
|
},
|
||||||
|
|
||||||
// 处理消息的准备状态 (MICRO_APP_READY)
|
// 处理消息的准备状态 (MICRO_APP_READY)
|
||||||
handleMessageOfReady(message) {
|
handleMessageOfReady({supportBeforeClose}) {
|
||||||
this.handleLoad()
|
this.handleLoad()
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
|
|
||||||
if (!message?.supportBeforeClose) {
|
if (!supportBeforeClose) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$store.commit('microApps/update', {
|
this.$store.commit('microApps/update', {
|
||||||
@ -151,7 +197,7 @@ export default {
|
|||||||
type: 'MICRO_APP_BEFORE_CLOSE',
|
type: 'MICRO_APP_BEFORE_CLOSE',
|
||||||
message
|
message
|
||||||
}, '*')
|
}, '*')
|
||||||
this.onBeforeClose[message.id] = resolve
|
this.pendingBeforeCloses.set(message.id, resolve)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,16 +205,11 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 处理方法消息 (MICRO_APP_METHOD)
|
// 处理方法消息 (MICRO_APP_METHOD)
|
||||||
handleMessageOfMethod(message) {
|
handleMessageOfMethod({id, method, args}) {
|
||||||
if (!this.data || !this.data.methods) {
|
if (!this.data || !this.data.methods || !this.data.methods[method]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const {id, method, args} = message;
|
|
||||||
if (!this.data.methods[method]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const postMessage = (result) => {
|
const postMessage = (result) => {
|
||||||
this.$refs.iframe.contentWindow.postMessage({
|
this.$refs.iframe.contentWindow.postMessage({
|
||||||
type: 'MICRO_APP_METHOD_RESULT',
|
type: 'MICRO_APP_METHOD_RESULT',
|
||||||
@ -183,21 +224,44 @@ export default {
|
|||||||
}, '*')
|
}, '*')
|
||||||
}
|
}
|
||||||
|
|
||||||
const before = this.data.methods[method](...args)
|
try {
|
||||||
|
const processedArgs = this.deserializeFunctions(args);
|
||||||
|
const before = this.data.methods[method](...processedArgs);
|
||||||
|
|
||||||
if (before && before.then) {
|
if (before && before.then) {
|
||||||
before.then(postMessage).catch(postError)
|
before.then(postMessage).catch(postError);
|
||||||
} else {
|
} else {
|
||||||
postMessage(before)
|
postMessage(before);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
postError(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理函数结果消息 (MICRO_APP_FUNCTION_RESULT)
|
||||||
|
handleMessageOfFunctionResult({callId, result, error}) {
|
||||||
|
const pending = this.pendingFunctionCalls.get(callId);
|
||||||
|
if (!pending) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingFunctionCalls.delete(callId);
|
||||||
|
clearTimeout(pending.timeout);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
pending.reject(new Error(error));
|
||||||
|
} else {
|
||||||
|
pending.resolve(result);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理方法消息 (MICRO_APP_BEFORE_CLOSE)
|
// 处理方法消息 (MICRO_APP_BEFORE_CLOSE)
|
||||||
handleMessageOfBeforeClose(message) {
|
handleMessageOfBeforeClose({id}) {
|
||||||
if (!this.onBeforeClose[message.id]) {
|
if (!this.pendingBeforeCloses.has(id)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.onBeforeClose[message.id]()
|
this.pendingBeforeCloses.get(id)()
|
||||||
delete this.onBeforeClose[message.id]
|
this.pendingBeforeCloses.delete(id)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 验证消息是否来自当前 iframe
|
// 验证消息是否来自当前 iframe
|
||||||
@ -211,6 +275,54 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 反序列化函数
|
||||||
|
deserializeFunctions(value) {
|
||||||
|
if (value && typeof value === 'object' && value.__func) {
|
||||||
|
return (...args) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const callId = `call_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
||||||
|
|
||||||
|
// 设置超时
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
this.pendingFunctionCalls.delete(callId);
|
||||||
|
reject(new Error('Function call timeout'));
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
// 存储待处理的调用
|
||||||
|
this.pendingFunctionCalls.set(callId, {
|
||||||
|
resolve,
|
||||||
|
reject,
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
|
||||||
|
// 发送函数调用请求
|
||||||
|
if (!this.$refs.iframe || !this.$refs.iframe.contentWindow) {
|
||||||
|
reject(new Error('Iframe not ready'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs.iframe.contentWindow.postMessage({
|
||||||
|
type: 'MICRO_APP_FUNCTION_CALL',
|
||||||
|
message: {funcId: value.__func, callId, args}
|
||||||
|
}, '*');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map(item => this.deserializeFunctions(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value && typeof value === 'object' && value.constructor === Object) {
|
||||||
|
const result = {};
|
||||||
|
for (const key in value) {
|
||||||
|
result[key] = this.deserializeFunctions(value[key]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
// 注入 microApp 对象到 iframe
|
// 注入 microApp 对象到 iframe
|
||||||
injectMicroApp() {
|
injectMicroApp() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user