perf: 优化微应用

This commit is contained in:
kuaifan 2025-08-06 22:22:47 +08:00
parent b73ab76bfb
commit 710609e98b
3 changed files with 35 additions and 34 deletions

View File

@ -96,7 +96,7 @@ services:
appstore: appstore:
container_name: "dootask-appstore-${APP_ID}" container_name: "dootask-appstore-${APP_ID}"
privileged: true privileged: true
image: "dootask/appstore:0.2.3" image: "dootask/appstore:0.2.4"
volumes: volumes:
- shared_data:/usr/share/dootask - shared_data:/usr/share/dootask
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock

View File

@ -117,6 +117,7 @@ export default {
assistShow: false, assistShow: false,
userSelectOptions: {value: [], config: {}}, userSelectOptions: {value: [], config: {}},
backupConfigs: {},
loadings: [], loadings: [],
closings: [], closings: [],
} }
@ -355,6 +356,7 @@ export default {
await this.externalWindow(config) await this.externalWindow(config)
return return
} }
this.backupConfigs[config.name] = $A.cloneJSON(config);
const app = this.microApps.find(({name}) => name == config.name); const app = this.microApps.find(({name}) => name == config.name);
if (app) { if (app) {
@ -540,10 +542,10 @@ export default {
/** /**
* 关闭之前判断 * 关闭之前判断
* @param name * @param name
* @param {boolean} isClick 是否是点击关闭 * @param {boolean} auto 当等于 true 并且是 keep_alive 的应用则不执行 onBeforeClose
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
onBeforeClose(name, isClick = false) { onBeforeClose(name, auto = false) {
return new Promise(resolve => { return new Promise(resolve => {
const onClose = () => { const onClose = () => {
if ($A.isSubElectron) { if ($A.isSubElectron) {
@ -559,8 +561,8 @@ export default {
onClose() onClose()
return return
} }
if (isClick && app.keep_alive) { if (auto && app.keep_alive) {
// keep_alive onBeforeClose // auto keep_alive onBeforeClose
onClose() onClose()
return return
} }
@ -635,16 +637,12 @@ export default {
this.closeMicroApp(name, true) this.closeMicroApp(name, true)
await new Promise(resolve => setTimeout(resolve, 300)); await new Promise(resolve => setTimeout(resolve, 300));
const app = this.microApps.find(item => item.name == name); const app = this.backupConfigs[name];
if (!app) { if (!app) {
$A.modalError("应用不存在"); $A.modalError("应用不存在");
return
} }
this.loadings.push(app.name) await this.onOpen(app)
requestAnimationFrame(_ => {
app.isOpen = true
app.lastOpenAt = Date.now()
this.$store.commit('microApps/keepAlive', 3)
})
}, },
/** /**

View File

@ -7,7 +7,7 @@
<transition :name="transitions[1]"> <transition :name="transitions[1]">
<div v-if="shouldRenderInDom" v-show="open" class="micro-modal-content" :style="contentStyle"> <div v-if="shouldRenderInDom" v-show="open" class="micro-modal-content" :style="contentStyle">
<!-- 工具栏移动端 --> <!-- 工具栏移动端 -->
<div v-if="capsuleMenuShow" class="micro-modal-capsule-mask"></div> <div v-if="capsuleMenuShow" class="micro-modal-cmask"></div>
<div class="micro-modal-capsule" :style="capsuleStyle"> <div class="micro-modal-capsule" :style="capsuleStyle">
<div class="micro-modal-capsule-item" @click="onCapsuleMore"> <div class="micro-modal-capsule-item" @click="onCapsuleMore">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -17,7 +17,7 @@
</svg> </svg>
</div> </div>
<div class="micro-modal-capsule-line"></div> <div class="micro-modal-capsule-line"></div>
<div class="micro-modal-capsule-item" @click="onClose(true)"> <div class="micro-modal-capsule-item" @click="onClose(false)">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16C12.866 16 16 12.866 16 9C16 5.13401 12.866 2 9 2C5.13401 2 2 5.13401 2 9C2 12.866 5.13401 16 9 16Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9 16C12.866 16 16 12.866 16 9C16 5.13401 12.866 2 9 2C5.13401 2 2 5.13401 2 9C2 12.866 5.13401 16 9 16Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 12C10.6569 12 12 10.6569 12 9C12 7.34315 10.6569 6 9 6C7.34315 6 6 7.34315 6 9C6 10.6569 7.34315 12 9 12Z" fill="currentColor"/> <path d="M9 12C10.6569 12 12 10.6569 12 9C12 7.34315 10.6569 6 9 6C7.34315 6 6 7.34315 6 9C6 10.6569 7.34315 12 9 12Z" fill="currentColor"/>
@ -52,7 +52,7 @@
@on-change="onChangeResize"/> @on-change="onChangeResize"/>
<!-- 窗口内容 --> <!-- 窗口内容 -->
<div ref="body" class="micro-modal-body" :class="bodyClass" :style="bodyStyle"> <div ref="body" class="micro-modal-body" :style="bodyStyle">
<slot></slot> <slot></slot>
</div> </div>
</div> </div>
@ -105,6 +105,7 @@ export default {
return { return {
'micro-modal': true, 'micro-modal': true,
'micro-modal-hidden': !this.open, 'micro-modal-hidden': !this.open,
'no-dark-content': !this.options.auto_dark_theme,
'transparent-mode': !!this.options.transparent, 'transparent-mode': !!this.options.transparent,
'capsule-mode': this.windowIsMobileLayout, 'capsule-mode': this.windowIsMobileLayout,
} }
@ -115,11 +116,6 @@ export default {
} }
return ['micro-modal-fade', 'micro-modal-slide'] return ['micro-modal-fade', 'micro-modal-slide']
}, },
bodyClass() {
return {
'no-dark-content': !this.options.auto_dark_theme,
}
},
bodyStyle() { bodyStyle() {
const styleObject = {} const styleObject = {}
if ($A.isJson(this.options.background)) { if ($A.isJson(this.options.background)) {
@ -136,8 +132,10 @@ export default {
const width = dynamicSize <= 100 ? `${dynamicSize}%` : `${dynamicSize}px` const width = dynamicSize <= 100 ? `${dynamicSize}%` : `${dynamicSize}px`
return {width, zIndex} return {width, zIndex}
}, },
capsuleStyle({zIndex}) { capsuleStyle() {
const styleObject = {zIndex} const styleObject = {
zIndex: this.zIndex + 1000
}
const {capsule} = this.options const {capsule} = this.options
if ($A.isJson(capsule)) { if ($A.isJson(capsule)) {
if (capsule.visible === false) { if (capsule.visible === false) {
@ -222,11 +220,11 @@ export default {
}) })
}, },
onClose(isClick = false) { onClose(auto = false) {
if (!this.beforeClose) { if (!this.beforeClose) {
return this.handleClose(); return this.handleClose();
} }
const before = this.beforeClose(this.options.name, isClick); const before = this.beforeClose(this.options.name, auto);
if (before && before.then) { if (before && before.then) {
before.then(() => { before.then(() => {
this.handleClose(); this.handleClose();
@ -252,7 +250,7 @@ export default {
// //
&.transparent-mode { &.transparent-mode {
--modal-mask-bg: transparent; --modal-mask-bg: transparent;
--modal-close-display: none; --modal-tool-display: none;
--modal-resize-display: none; --modal-resize-display: none;
--modal-content-left: 0; --modal-content-left: 0;
--modal-content-min-width: 100%; --modal-content-min-width: 100%;
@ -263,14 +261,14 @@ export default {
// //
&.capsule-mode { &.capsule-mode {
--modal-tool-display: none;
--modal-capsule-display: flex; --modal-capsule-display: flex;
--modal-close-display: none;
} }
// //
@media (max-width: 768px) { @media (max-width: 768px) {
--modal-mask-bg: transparent; --modal-mask-bg: transparent;
--modal-close-display: none; --modal-tool-display: none;
--modal-resize-display: none; --modal-resize-display: none;
--modal-content-left: 0; --modal-content-left: 0;
--modal-content-min-width: 100%; --modal-content-min-width: 100%;
@ -295,25 +293,27 @@ export default {
} }
&-mask { &-mask {
filter: var(--modal-dark-filter, none);
position: fixed; position: fixed;
top: 0; top: 0;
bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0;
background-color: var(--modal-mask-bg, rgba(0, 0, 0, .4)); background-color: var(--modal-mask-bg, rgba(0, 0, 0, .4));
} }
&-capsule-mask { &-cmask {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: transparent;
z-index: 1; z-index: 1;
background-color: transparent;
} }
&-capsule { &-capsule {
filter: var(--modal-dark-filter, none);
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
@ -354,6 +354,7 @@ export default {
svg { svg {
width: 20px; width: 20px;
height: 20px; height: 20px;
color: #303133;
transition: color 0.2s; transition: color 0.2s;
pointer-events: none; pointer-events: none;
} }
@ -361,13 +362,14 @@ export default {
} }
&-tools { &-tools {
filter: var(--modal-dark-filter, none);
position: absolute; position: absolute;
top: var(--status-bar-height, 0); top: var(--status-bar-height, 0);
left: -40px; left: -40px;
z-index: 2; z-index: 2;
min-width: 40px; min-width: 40px;
min-height: 40px; min-height: 40px;
display: var(--modal-close-display, black); display: var(--modal-tool-display, black);
overflow: hidden; overflow: hidden;
> div { > div {
@ -376,7 +378,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: var(--modal-close-color, #ffffff); color: var(--modal-tool-color, #ffffff);
cursor: pointer; cursor: pointer;
&:hover { &:hover {
@ -500,9 +502,10 @@ body.dark-mode-reverse {
.micro-modal { .micro-modal {
&:not(.transparent-mode) { &:not(.transparent-mode) {
--modal-mask-bg: rgba(230, 230, 230, 0.6); --modal-mask-bg: rgba(230, 230, 230, 0.6);
--modal-close-color: #323232; --modal-tool-color: #000000;
.no-dark-content { &.no-dark-content {
--modal-dark-filter: invert(100%) hue-rotate(180deg) contrast(100%);
--modal-body-background-color: #000000; --modal-body-background-color: #000000;
} }
} }