perf: 优化应用中心

This commit is contained in:
kuaifan 2025-07-15 13:55:12 +08:00
parent 6426e0238a
commit 898656963d
5 changed files with 99 additions and 28 deletions

View File

@ -37,6 +37,7 @@ export default {
data() { data() {
return { return {
src: this.url, src: this.url,
onBeforeClose: {},
} }
}, },
@ -87,8 +88,26 @@ export default {
switch (type) { switch (type) {
case 'MICRO_APP_READY': case 'MICRO_APP_READY':
this.injectMicroApp() this.injectMicroApp()
this.$store.commit('microApps/update', {
name: this.name,
data: {
onBeforeClose: () => {
return new Promise(resolve => {
const message = {
id: $A.randomString(16),
name: this.name
}
this.$refs.iframe.contentWindow.postMessage({
type: 'MICRO_APP_BEFORE_CLOSE',
message
}, '*')
this.onBeforeClose[message.id] = resolve
})
}
}
})
break break
case 'MICRO_APP_METHOD': case 'MICRO_APP_METHOD':
if (!this.data || !this.data.methods) { if (!this.data || !this.data.methods) {
return return
@ -109,6 +128,14 @@ export default {
} }
} }
break break
case 'MICRO_APP_BEFORE_CLOSE':
if (this.onBeforeClose[message.id]) {
this.onBeforeClose[message.id]()
delete this.onBeforeClose[message.id]
}
break
default: default:
break break
} }
@ -117,7 +144,7 @@ export default {
// iframe // iframe
isFromCurrentIframe(event) { isFromCurrentIframe(event) {
try { try {
const { source } = event const {source} = event
return this.$refs.iframe && source === this.$refs.iframe.contentWindow return this.$refs.iframe && source === this.$refs.iframe.contentWindow
} catch (error) { } catch (error) {
// console.error('Failed to validate message from current iframe:', error) // console.error('Failed to validate message from current iframe:', error)

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<MicroModal <MicroModal
v-for="(app, key) in apps" v-for="(app, key) in microApps"
:key="key" :key="key"
v-model="app.isOpen" v-model="app.isOpen"
:ref="`ref-${app.name}`" :ref="`ref-${app.name}`"
@ -107,7 +107,6 @@ export default {
data() { data() {
return { return {
apps: [],
assistShow: false, assistShow: false,
userSelectOptions: {value: [], config: {}}, userSelectOptions: {value: [], config: {}},
} }
@ -139,9 +138,9 @@ export default {
themeName() { themeName() {
this.closeAllMicroApp() this.closeAllMicroApp()
}, },
apps: { microApps: {
handler(apps) { handler(items) {
this.assistShow = !!apps.find(item => item.isOpen) this.assistShow = !!items.find(item => item.isOpen)
}, },
deep: true, deep: true,
} }
@ -151,6 +150,7 @@ export default {
...mapState([ ...mapState([
'userInfo', 'userInfo',
'themeName', 'themeName',
'microApps',
]), ]),
}, },
@ -175,10 +175,7 @@ export default {
// //
finish(name) { finish(name) {
const app = this.apps.find(app => app.name == name); this.$store.commit('microApps/update', {name, data: {isLoading: false}})
if (app) {
app.isLoading = false
}
}, },
/** /**
@ -187,7 +184,7 @@ export default {
* @returns {*} * @returns {*}
*/ */
appData(name) { appData(name) {
const app = this.apps.find(item => item.name == name); const app = this.microApps.find(item => item.name == name);
if (!app) { if (!app) {
return {}; return {};
} }
@ -238,7 +235,7 @@ export default {
this.closeByName(name) this.closeByName(name)
}, },
popoutWindow: async (windowConfig = null) => { popoutWindow: async (windowConfig = null) => {
const app = this.apps.find(item => item.name == name); const app = this.microApps.find(item => item.name == name);
if (!app) { if (!app) {
$A.modalError("应用不存在"); $A.modalError("应用不存在");
return return
@ -272,7 +269,7 @@ export default {
}, },
}); });
}, },
requestAPI: async(params) => { requestAPI: async (params) => {
return await store.dispatch('call', params); return await store.dispatch('call', params);
}, },
selectUsers: async (params) => { selectUsers: async (params) => {
@ -307,6 +304,9 @@ export default {
} }
return null; return null;
}, },
isFullScreen: () => {
return window.innerWidth < 768 || this.windowType === 'popout'
},
}, },
} }
}, },
@ -316,7 +316,7 @@ export default {
* @param config * @param config
*/ */
async observeMicroApp(config) { async observeMicroApp(config) {
if (config.url_type === 'inline_blank') { if (/_blank$/i.test(config.url_type)) {
await this.inlineBlank(config) await this.inlineBlank(config)
return return
} }
@ -325,7 +325,7 @@ export default {
return return
} }
const app = this.apps.find(({name}) => name == config.name); const app = this.microApps.find(({name}) => name == config.name);
if (app) { if (app) {
// //
if (app.url != config.url) { if (app.url != config.url) {
@ -338,7 +338,8 @@ export default {
// //
config.isLoading = true config.isLoading = true
config.isOpen = false config.isOpen = false
this.apps.push(config) config.onBeforeClose = () => true
this.$store.commit('microApps/push', config)
requestAnimationFrame(_ => config.isOpen = true) requestAnimationFrame(_ => config.isOpen = true)
} }
}, },
@ -353,7 +354,7 @@ export default {
const appConfig = { const appConfig = {
...config, ...config,
url_type: config.url_type === 'iframe' ? 'iframe' : 'inline', url_type: config.url_type.replace(/_blank$/, ''),
transparent: true, transparent: true,
keep_alive: false, keep_alive: false,
}; };
@ -444,7 +445,7 @@ export default {
* @param destroy * @param destroy
*/ */
closeMicroApp(name, destroy) { closeMicroApp(name, destroy) {
const app = this.apps.find(item => item.name == name); const app = this.microApps.find(item => item.name == name);
if (!app) { if (!app) {
return; return;
} }
@ -460,7 +461,7 @@ export default {
* @param destroy * @param destroy
*/ */
closeAllMicroApp(destroy = true) { closeAllMicroApp(destroy = true) {
this.apps.forEach(app => { this.microApps.forEach(app => {
app.isOpen = false app.isOpen = false
if (destroy) { if (destroy) {
microApp.unmountApp(app.name, {destroy: true}) microApp.unmountApp(app.name, {destroy: true})
@ -475,16 +476,38 @@ export default {
*/ */
onBeforeClose(name) { onBeforeClose(name) {
return new Promise(resolve => { return new Promise(resolve => {
const onClose = () => {
if ($A.isSubElectron) {
$A.Electron.sendMessage('windowDestroy');
} else {
resolve()
}
}
const app = this.microApps.find(item => item.name == name);
if (!app) {
onClose()
return
}
if (/^iframe/i.test(app.url_type)) {
const before = app.onBeforeClose();
if (before && before.then) {
before.then(() => {
onClose()
});
} else {
onClose()
}
return
}
microApp.forceSetData(name, {type: 'beforeClose'}, array => { microApp.forceSetData(name, {type: 'beforeClose'}, array => {
if (!array?.find(item => item === true)) { if (!array?.find(item => item === true)) {
if ($A.leftExists(name, 'appstore')) { if ($A.leftExists(name, 'appstore')) {
this.$store.dispatch("updateMicroAppsStatus"); this.$store.dispatch("updateMicroAppsStatus");
} }
if ($A.isSubElectron) { onClose()
$A.Electron.sendMessage('windowDestroy');
} else {
resolve()
}
} }
}) })
}) })
@ -496,7 +519,7 @@ export default {
*/ */
onAssistClose() { onAssistClose() {
return new Promise(resolve => { return new Promise(resolve => {
const app = this.apps.findLast(item => item.isOpen) const app = this.microApps.findLast(item => item.isOpen)
if (app) { if (app) {
this.closeByName(app.name) this.closeByName(app.name)
} else { } else {

View File

@ -178,8 +178,8 @@ export default {
--modal-body-background-color: transparent; --modal-body-background-color: transparent;
} }
// //
@media (max-width: 500px) { @media (max-width: 768px) {
--modal-mask-bg: transparent; --modal-mask-bg: transparent;
--modal-close-display: none; --modal-close-display: none;
--modal-resize-display: none; --modal-resize-display: none;
@ -313,6 +313,7 @@ body.dark-mode-reverse {
--modal-mask-bg: rgba(230, 230, 230, 0.6); --modal-mask-bg: rgba(230, 230, 230, 0.6);
--modal-close-color: #323232; --modal-close-color: #323232;
} }
&.no-dark-content { &.no-dark-content {
--modal-mask-bg: rgba(20, 20, 20, 0.6); --modal-mask-bg: rgba(20, 20, 20, 0.6);
--modal-body-background-color: #000000; --modal-body-background-color: #000000;

View File

@ -300,6 +300,25 @@ export default {
}, },
// 微应用管理 // 微应用管理
'microApps/push': function(state, data) {
state.microApps.push(data)
},
'microApps/update': function(state, {name, data}) {
const app = state.microApps.find(item => item.name == name)
if (app) {
Object.assign(app, data)
}
},
'microApps/splice': function(state, {index, data, count = 1}) {
if (typeof data === "undefined") {
state.microApps.splice(index, count)
} else {
state.microApps.splice(index, count, data)
}
},
'microApps/data': function(state, data) { 'microApps/data': function(state, data) {
data.unshift({ data.unshift({
id: 'appstore', id: 'appstore',

View File

@ -267,6 +267,7 @@ export default {
longpressData: {type: '', data: null, element: null}, longpressData: {type: '', data: null, element: null},
// 微应用数据 // 微应用数据
microApps: [],
microAppsIds: [], microAppsIds: [],
microAppsMenus: [], microAppsMenus: [],
}; };