mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 19:35:50 +00:00
perf: 优化微应用
This commit is contained in:
parent
27b64df870
commit
b73ab76bfb
@ -196,10 +196,19 @@ export default {
|
|||||||
this.$store.commit('microApps/update', {
|
this.$store.commit('microApps/update', {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
data: {
|
data: {
|
||||||
|
postMessage: (message) => {
|
||||||
|
if (!this.$refs.iframe || !this.$refs.iframe.contentWindow) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.iframe.contentWindow.postMessage(message, '*')
|
||||||
|
},
|
||||||
onBeforeClose: () => {
|
onBeforeClose: () => {
|
||||||
if (this.hearTbeatLastTime && Date.now() - this.hearTbeatLastTime > 5000) {
|
if (this.hearTbeatLastTime && Date.now() - this.hearTbeatLastTime > 5000) {
|
||||||
return true // 超时,允许关闭
|
return true // 超时,允许关闭
|
||||||
}
|
}
|
||||||
|
if (!this.$refs.iframe || !this.$refs.iframe.contentWindow) {
|
||||||
|
return true // iframe 不存在,允许关闭
|
||||||
|
}
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const message = {
|
const message = {
|
||||||
id: $A.randomString(16),
|
id: $A.randomString(16),
|
||||||
|
|||||||
@ -3,16 +3,14 @@
|
|||||||
<MicroModal
|
<MicroModal
|
||||||
v-for="(app, key) in microApps"
|
v-for="(app, key) in microApps"
|
||||||
:key="key"
|
:key="key"
|
||||||
v-model="app.isOpen"
|
:open="app.isOpen"
|
||||||
:ref="`ref-${app.name}`"
|
:ref="`ref-${app.name}`"
|
||||||
:size="1200"
|
:size="1200"
|
||||||
:background="app.background"
|
:options="app"
|
||||||
:transparent="app.transparent"
|
:beforeClose="onBeforeClose"
|
||||||
:autoDarkTheme="app.auto_dark_theme"
|
@on-capsule-more="onCapsuleMore"
|
||||||
:keepAlive="app.keep_alive"
|
@on-popout-window="onPopoutWindow"
|
||||||
:beforeClose="async (isClick) => { await onBeforeClose(app.name, isClick) }"
|
@on-close="closeMicroApp">
|
||||||
@on-restart-app="onRestartApp(app.name)"
|
|
||||||
@on-popout-window="onPopoutWindow(app.name)">
|
|
||||||
<MicroIFrame
|
<MicroIFrame
|
||||||
v-if="shouldRenderIFrame(app)"
|
v-if="shouldRenderIFrame(app)"
|
||||||
:name="app.name"
|
:name="app.name"
|
||||||
@ -22,7 +20,7 @@
|
|||||||
@mounted="mounted"
|
@mounted="mounted"
|
||||||
@error="error"/>
|
@error="error"/>
|
||||||
<micro-app
|
<micro-app
|
||||||
v-else-if="app.isOpen && app.url"
|
v-else-if="shouldRenderMicro(app)"
|
||||||
:name="app.name"
|
:name="app.name"
|
||||||
:url="app.url"
|
:url="app.url"
|
||||||
:keep-alive="app.keep_alive"
|
:keep-alive="app.keep_alive"
|
||||||
@ -30,10 +28,14 @@
|
|||||||
:data="appData(app.name)"
|
:data="appData(app.name)"
|
||||||
@mounted="mounted"
|
@mounted="mounted"
|
||||||
@error="error"/>
|
@error="error"/>
|
||||||
<div v-if="app.isLoading" class="micro-app-loader">
|
</MicroModal>
|
||||||
|
|
||||||
|
<!--加载中-->
|
||||||
|
<transition name="fade">
|
||||||
|
<div v-if="loadings.length > 0" class="micro-app-loader">
|
||||||
<Loading/>
|
<Loading/>
|
||||||
</div>
|
</div>
|
||||||
</MicroModal>
|
</transition>
|
||||||
|
|
||||||
<!--选择用户-->
|
<!--选择用户-->
|
||||||
<UserSelect
|
<UserSelect
|
||||||
@ -58,6 +60,7 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.micro-app-loader {
|
.micro-app-loader {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
z-index: 9999;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -113,6 +116,9 @@ export default {
|
|||||||
return {
|
return {
|
||||||
assistShow: false,
|
assistShow: false,
|
||||||
userSelectOptions: {value: [], config: {}},
|
userSelectOptions: {value: [], config: {}},
|
||||||
|
|
||||||
|
loadings: [],
|
||||||
|
closings: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -122,8 +128,8 @@ export default {
|
|||||||
|
|
||||||
// 初始化微应用
|
// 初始化微应用
|
||||||
microApp.start({
|
microApp.start({
|
||||||
'iframe': true,
|
|
||||||
'router-mode': 'state',
|
'router-mode': 'state',
|
||||||
|
'iframe': true,
|
||||||
'iframeSrc': window.location.origin + '/assets/empty.html',
|
'iframeSrc': window.location.origin + '/assets/empty.html',
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -193,7 +199,7 @@ export default {
|
|||||||
|
|
||||||
// 加载结束
|
// 加载结束
|
||||||
finish(name) {
|
finish(name) {
|
||||||
this.$store.commit('microApps/update', {name, data: {isLoading: false}})
|
this.loadings = this.loadings.filter(item => item !== name);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,9 +365,9 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新微应用
|
// 更新微应用
|
||||||
if (app.url != config.url) {
|
if (app.url != config.url || !app.keep_alive) {
|
||||||
this.unmountMicroApp(app)
|
this.unmountMicroApp(app)
|
||||||
app.isLoading = true
|
this.loadings.push(app.name)
|
||||||
}
|
}
|
||||||
Object.assign(app, config)
|
Object.assign(app, config)
|
||||||
requestAnimationFrame(_ => {
|
requestAnimationFrame(_ => {
|
||||||
@ -371,10 +377,11 @@ export default {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 新建微应用
|
// 新建微应用
|
||||||
config.isLoading = true
|
|
||||||
config.isOpen = false
|
config.isOpen = false
|
||||||
|
config.postMessage = () => {}
|
||||||
config.onBeforeClose = () => true
|
config.onBeforeClose = () => true
|
||||||
this.$store.commit('microApps/push', config)
|
this.$store.commit('microApps/push', config)
|
||||||
|
this.loadings.push(config.name)
|
||||||
requestAnimationFrame(_ => {
|
requestAnimationFrame(_ => {
|
||||||
config.isOpen = true
|
config.isOpen = true
|
||||||
config.lastOpenAt = Date.now()
|
config.lastOpenAt = Date.now()
|
||||||
@ -401,7 +408,7 @@ export default {
|
|||||||
appConfig.url = windowConfig.url;
|
appConfig.url = windowConfig.url;
|
||||||
delete windowConfig.url;
|
delete windowConfig.url;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
const path = `/single/apps/${appConfig.name}`
|
const path = `/single/apps/${appConfig.name}`
|
||||||
const apps = (await $A.IDBArray("cacheMicroApps")).filter(item => item.name != appConfig.name);
|
const apps = (await $A.IDBArray("cacheMicroApps")).filter(item => item.name != appConfig.name);
|
||||||
apps.length > 50 && apps.splice(0, 10)
|
apps.length > 50 && apps.splice(0, 10)
|
||||||
@ -466,6 +473,19 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭微应用状态
|
||||||
|
* @param {Object} app 微应用对象
|
||||||
|
* @param app
|
||||||
|
*/
|
||||||
|
closeAppState(app) {
|
||||||
|
this.closings.push(app.name);
|
||||||
|
app.isOpen = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.closings = this.closings.filter(item => item !== app.name);
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭微应用(关闭前执行beforeClose)
|
* 关闭微应用(关闭前执行beforeClose)
|
||||||
* @param name
|
* @param name
|
||||||
@ -483,28 +503,18 @@ export default {
|
|||||||
* @param name
|
* @param name
|
||||||
* @param destroy
|
* @param destroy
|
||||||
*/
|
*/
|
||||||
closeMicroApp(name, destroy) {
|
closeMicroApp(name, destroy = false) {
|
||||||
const app = this.microApps.find(item => item.name == name);
|
const app = this.microApps.find(item => item.name == name);
|
||||||
if (!app) {
|
if (!app) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
app.isOpen = false
|
this.closeAppState(app)
|
||||||
if (destroy) {
|
if (destroy === true) {
|
||||||
this.unmountMicroApp(app)
|
this.unmountMicroApp(app)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 卸载所有微应用
|
|
||||||
*/
|
|
||||||
unmountAllMicroApp() {
|
|
||||||
this.microApps.forEach(app => {
|
|
||||||
app.isOpen = false
|
|
||||||
this.unmountMicroApp(app)
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 卸载微应用
|
* 卸载微应用
|
||||||
* @param app
|
* @param app
|
||||||
@ -517,6 +527,16 @@ export default {
|
|||||||
microApp.unmountApp(app.name, {destroy: true})
|
microApp.unmountApp(app.name, {destroy: true})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卸载所有微应用
|
||||||
|
*/
|
||||||
|
unmountAllMicroApp() {
|
||||||
|
this.microApps.forEach(app => {
|
||||||
|
this.closeAppState(app)
|
||||||
|
this.unmountMicroApp(app)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭之前判断
|
* 关闭之前判断
|
||||||
* @param name
|
* @param name
|
||||||
@ -545,7 +565,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/^iframe/i.test(app.url_type)) {
|
if (this.isIframe(app.url_type)) {
|
||||||
const before = app.onBeforeClose();
|
const before = app.onBeforeClose();
|
||||||
if (before && before.then) {
|
if (before && before.then) {
|
||||||
before.then(() => {
|
before.then(() => {
|
||||||
@ -583,6 +603,30 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击更多操作
|
||||||
|
* @param name
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
onCapsuleMore(name, action) {
|
||||||
|
if (action === 'restart') {
|
||||||
|
this.onRestartApp(name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const app = this.microApps.find(item => item.name == name);
|
||||||
|
if (!app) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.isIframe(app.url_type)) {
|
||||||
|
app.postMessage({
|
||||||
|
type: 'MICRO_APP_MENU_CLICK',
|
||||||
|
message: action
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
microApp.forceSetData(name, {type: 'menuClick', message: action})
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重启应用
|
* 重启应用
|
||||||
* @param name
|
* @param name
|
||||||
@ -595,7 +639,7 @@ export default {
|
|||||||
if (!app) {
|
if (!app) {
|
||||||
$A.modalError("应用不存在");
|
$A.modalError("应用不存在");
|
||||||
}
|
}
|
||||||
app.isLoading = true;
|
this.loadings.push(app.name)
|
||||||
requestAnimationFrame(_ => {
|
requestAnimationFrame(_ => {
|
||||||
app.isOpen = true
|
app.isOpen = true
|
||||||
app.lastOpenAt = Date.now()
|
app.lastOpenAt = Date.now()
|
||||||
@ -618,13 +662,31 @@ export default {
|
|||||||
this.closeMicroApp(name, true)
|
this.closeMicroApp(name, true)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否 iframe 类型
|
||||||
|
* @param type
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isIframe(type) {
|
||||||
|
return /^iframe/i.test(type)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否渲染 iframe
|
* 是否渲染 iframe
|
||||||
* @param app
|
* @param app
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
shouldRenderIFrame(app) {
|
shouldRenderIFrame(app) {
|
||||||
return app.url_type === 'iframe' && (app.isOpen || app.keep_alive) && app.url;
|
return app.url && this.isIframe(app.url_type) && (app.isOpen || app.keep_alive);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否渲染 micro
|
||||||
|
* @param app
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
shouldRenderMicro(app) {
|
||||||
|
return app.url && !this.isIframe(app.url_type) && (app.isOpen || this.closings.includes(app.name));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,11 +2,12 @@
|
|||||||
<div v-transfer-dom :data-transfer="true">
|
<div v-transfer-dom :data-transfer="true">
|
||||||
<div :class="className">
|
<div :class="className">
|
||||||
<transition :name="transitions[0]">
|
<transition :name="transitions[0]">
|
||||||
<div v-if="shouldRenderInDom" v-show="value" class="micro-modal-mask" @click="onClose(false)" :style="maskStyle"></div>
|
<div v-if="shouldRenderInDom" v-show="open" class="micro-modal-mask" @click="onClose(false)" :style="maskStyle"></div>
|
||||||
</transition>
|
</transition>
|
||||||
<transition :name="transitions[1]">
|
<transition :name="transitions[1]">
|
||||||
<div v-if="shouldRenderInDom" v-show="value" 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 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">
|
||||||
@ -23,6 +24,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 工具栏(桌面端) -->
|
<!-- 工具栏(桌面端) -->
|
||||||
<div class="micro-modal-tools" :class="{expanded: $A.isMainElectron}">
|
<div class="micro-modal-tools" :class="{expanded: $A.isMainElectron}">
|
||||||
<div class="tool-close" @click="onClose(true)">
|
<div class="tool-close" @click="onClose(true)">
|
||||||
@ -30,13 +32,14 @@
|
|||||||
<path d="M8.28596 6.51819C7.7978 6.03003 7.00634 6.03003 6.51819 6.51819C6.03003 7.00634 6.03003 7.7978 6.51819 8.28596L11.2322 13L6.51819 17.714C6.03003 18.2022 6.03003 18.9937 6.51819 19.4818C7.00634 19.97 7.7978 19.97 8.28596 19.4818L13 14.7678L17.714 19.4818C18.2022 19.97 18.9937 19.97 19.4818 19.4818C19.97 18.9937 19.97 18.2022 19.4818 17.714L14.7678 13L19.4818 8.28596C19.97 7.7978 19.97 7.00634 19.4818 6.51819C18.9937 6.03003 18.2022 6.03003 17.714 6.51819L13 11.2322L8.28596 6.51819Z" fill="currentColor"></path>
|
<path d="M8.28596 6.51819C7.7978 6.03003 7.00634 6.03003 6.51819 6.51819C6.03003 7.00634 6.03003 7.7978 6.51819 8.28596L11.2322 13L6.51819 17.714C6.03003 18.2022 6.03003 18.9937 6.51819 19.4818C7.00634 19.97 7.7978 19.97 8.28596 19.4818L13 14.7678L17.714 19.4818C18.2022 19.97 18.9937 19.97 19.4818 19.4818C19.97 18.9937 19.97 18.2022 19.4818 17.714L14.7678 13L19.4818 8.28596C19.97 7.7978 19.97 7.00634 19.4818 6.51819C18.9937 6.03003 18.2022 6.03003 17.714 6.51819L13 11.2322L8.28596 6.51819Z" fill="currentColor"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-fullscreen" @click="$emit('on-popout-window')">
|
<div class="tool-fullscreen" @click="$emit('on-popout-window', options.name)">
|
||||||
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M682.666667 298.666667H170.666667c-47.061333 0-85.333333 38.272-85.333334 85.333333v426.666667c0 47.061333 38.272 85.333333 85.333334 85.333333h512c47.061333 0 85.333333-38.272 85.333333-85.333333V384c0-47.061333-38.272-85.333333-85.333333-85.333333zM170.666667 810.666667v-341.333334h512V384l0.085333 426.666667H170.666667z" fill="currentColor"></path>
|
<path d="M682.666667 298.666667H170.666667c-47.061333 0-85.333333 38.272-85.333334 85.333333v426.666667c0 47.061333 38.272 85.333333 85.333334 85.333333h512c47.061333 0 85.333333-38.272 85.333333-85.333333V384c0-47.061333-38.272-85.333333-85.333333-85.333333zM170.666667 810.666667v-341.333334h512V384l0.085333 426.666667H170.666667z" fill="currentColor"></path>
|
||||||
<path d="M938.666667 213.333333c0-47.061333-38.272-85.333333-85.333334-85.333333H298.666667c-47.061333 0-85.333333 38.272-85.333334 85.333333h554.709334c46.976 0 85.162667 38.186667 85.290666 85.077334L853.418667 640H853.333333v85.333333c47.061333 0 85.333333-38.272 85.333334-85.333333V341.632L938.709333 341.333333V256L938.666667 255.573333V213.333333z" fill="currentColor"></path>
|
<path d="M938.666667 213.333333c0-47.061333-38.272-85.333333-85.333334-85.333333H298.666667c-47.061333 0-85.333333 38.272-85.333334 85.333333h554.709334c46.976 0 85.162667 38.186667 85.290666 85.077334L853.418667 640H853.333333v85.333333c47.061333 0 85.333333-38.272 85.333334-85.333333V341.632L938.709333 341.333333V256L938.666667 255.573333V213.333333z" fill="currentColor"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 窗口大小调整(桌面端) -->
|
<!-- 窗口大小调整(桌面端) -->
|
||||||
<ResizeLine
|
<ResizeLine
|
||||||
class="micro-modal-resize"
|
class="micro-modal-resize"
|
||||||
@ -47,8 +50,9 @@
|
|||||||
:reverse="true"
|
:reverse="true"
|
||||||
:beforeResize="beforeResize"
|
:beforeResize="beforeResize"
|
||||||
@on-change="onChangeResize"/>
|
@on-change="onChangeResize"/>
|
||||||
|
|
||||||
<!-- 窗口内容 -->
|
<!-- 窗口内容 -->
|
||||||
<div ref="body" class="micro-modal-body" :style="bodyStyle">
|
<div ref="body" class="micro-modal-body" :class="bodyClass" :style="bodyStyle">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -67,7 +71,7 @@ export default {
|
|||||||
components: {ResizeLine},
|
components: {ResizeLine},
|
||||||
directives: {TransferDom},
|
directives: {TransferDom},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
open: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
@ -79,55 +83,49 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 300
|
default: 300
|
||||||
},
|
},
|
||||||
background: {
|
options: {
|
||||||
default: null
|
type: Object,
|
||||||
},
|
default: () => ({})
|
||||||
transparent: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
autoDarkTheme: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
keepAlive: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
},
|
||||||
beforeClose: Function
|
beforeClose: Function
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dynamicSize: 0,
|
dynamicSize: 0,
|
||||||
zIndex: 1000
|
zIndex: 1000,
|
||||||
|
capsuleMenuShow: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['windowIsMobileLayout']),
|
...mapState(['windowIsMobileLayout']),
|
||||||
shouldRenderInDom() {
|
shouldRenderInDom() {
|
||||||
return this.value || this.keepAlive;
|
return this.open || !!this.options.keep_alive;
|
||||||
},
|
},
|
||||||
className({value, autoDarkTheme, transparent, windowIsMobileLayout}) {
|
className() {
|
||||||
return {
|
return {
|
||||||
'micro-modal': true,
|
'micro-modal': true,
|
||||||
'micro-modal-hidden': !value,
|
'micro-modal-hidden': !this.open,
|
||||||
'no-dark-content': !autoDarkTheme,
|
'transparent-mode': !!this.options.transparent,
|
||||||
'transparent-mode': transparent,
|
'capsule-mode': this.windowIsMobileLayout,
|
||||||
'capsule-mode': windowIsMobileLayout,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transitions({transparent}) {
|
transitions() {
|
||||||
if (transparent) {
|
if (!!this.options.transparent) {
|
||||||
return ['', '']
|
return ['', '']
|
||||||
}
|
}
|
||||||
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.background)) {
|
if ($A.isJson(this.options.background)) {
|
||||||
styleObject.background = this.background
|
styleObject.background = this.options.background
|
||||||
} else if (this.background) {
|
} else if (this.options.background) {
|
||||||
styleObject.backgroundColor = this.background;
|
styleObject.backgroundColor = this.options.background;
|
||||||
}
|
}
|
||||||
return styleObject;
|
return styleObject;
|
||||||
},
|
},
|
||||||
@ -139,11 +137,24 @@ export default {
|
|||||||
return {width, zIndex}
|
return {width, zIndex}
|
||||||
},
|
},
|
||||||
capsuleStyle({zIndex}) {
|
capsuleStyle({zIndex}) {
|
||||||
return {zIndex}
|
const styleObject = {zIndex}
|
||||||
|
const {capsule} = this.options
|
||||||
|
if ($A.isJson(capsule)) {
|
||||||
|
if (capsule.visible === false) {
|
||||||
|
styleObject.display = 'none';
|
||||||
|
}
|
||||||
|
if (typeof capsule.top === 'number') {
|
||||||
|
styleObject.top = `${capsule.top}px`;
|
||||||
|
}
|
||||||
|
if (typeof capsule.right === 'number') {
|
||||||
|
styleObject.right = `${capsule.right}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return styleObject
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value: {
|
open: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.zIndex = typeof window.modalTransferIndex === 'number' ? window.modalTransferIndex++ : 1000;
|
this.zIndex = typeof window.modalTransferIndex === 'number' ? window.modalTransferIndex++ : 1000;
|
||||||
@ -181,19 +192,31 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onCapsuleMore(event) {
|
onCapsuleMore(event) {
|
||||||
const list = [
|
const list = [];
|
||||||
{label: '重启应用', value: 'restart'},
|
const {capsule} = this.options;
|
||||||
{label: '关闭应用', value: 'close'},
|
if ($A.isJson(capsule) && $A.isArray(capsule.more_menus)) {
|
||||||
];
|
capsule.more_menus.forEach(item => {
|
||||||
|
if (item.label && item.value) {
|
||||||
|
list.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
list.push(...[
|
||||||
|
{label: this.$L('重启应用'), value: 'restart', divided: list.length > 0},
|
||||||
|
{label: this.$L('关闭应用'), value: 'close'},
|
||||||
|
])
|
||||||
this.$store.commit('menu/operation', {
|
this.$store.commit('menu/operation', {
|
||||||
event,
|
event,
|
||||||
list,
|
list,
|
||||||
size: 'large',
|
size: 'large',
|
||||||
|
onVisibleChange: (visible) => {
|
||||||
|
this.capsuleMenuShow = visible;
|
||||||
|
},
|
||||||
onUpdate: (value) => {
|
onUpdate: (value) => {
|
||||||
if (value === 'restart') {
|
if (value === 'close') {
|
||||||
this.$emit('on-restart-app');
|
|
||||||
} else if (value === 'close') {
|
|
||||||
this.onClose(true);
|
this.onClose(true);
|
||||||
|
} else {
|
||||||
|
this.$emit('on-capsule-more', this.options.name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -203,7 +226,7 @@ export default {
|
|||||||
if (!this.beforeClose) {
|
if (!this.beforeClose) {
|
||||||
return this.handleClose();
|
return this.handleClose();
|
||||||
}
|
}
|
||||||
const before = this.beforeClose(isClick);
|
const before = this.beforeClose(this.options.name, isClick);
|
||||||
if (before && before.then) {
|
if (before && before.then) {
|
||||||
before.then(() => {
|
before.then(() => {
|
||||||
this.handleClose();
|
this.handleClose();
|
||||||
@ -214,7 +237,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.$emit('input', false)
|
this.$emit('on-close', this.options.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,10 +303,20 @@ export default {
|
|||||||
background-color: var(--modal-mask-bg, rgba(0, 0, 0, .4));
|
background-color: var(--modal-mask-bg, rgba(0, 0, 0, .4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-capsule-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&-capsule {
|
&-capsule {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 10px;
|
||||||
right: 8px;
|
right: 10px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
transform: translateY(var(--status-bar-height, 0));
|
transform: translateY(var(--status-bar-height, 0));
|
||||||
display: var(--modal-capsule-display, none);
|
display: var(--modal-capsule-display, none);
|
||||||
@ -466,13 +499,10 @@ export default {
|
|||||||
body.dark-mode-reverse {
|
body.dark-mode-reverse {
|
||||||
.micro-modal {
|
.micro-modal {
|
||||||
&:not(.transparent-mode) {
|
&:not(.transparent-mode) {
|
||||||
&:not(.no-dark-content) {
|
--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-body-background-color: #000000;
|
--modal-body-background-color: #000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2642,6 +2642,7 @@ export default {
|
|||||||
name: 'okr_details',
|
name: 'okr_details',
|
||||||
url: 'apps/okr/#details',
|
url: 'apps/okr/#details',
|
||||||
props: {type: 'details', id},
|
props: {type: 'details', id},
|
||||||
|
keep_alive: false,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
1
resources/assets/js/store/actions.js
vendored
1
resources/assets/js/store/actions.js
vendored
@ -4745,6 +4745,7 @@ export default {
|
|||||||
url: $A.mainUrl(data.url),
|
url: $A.mainUrl(data.url),
|
||||||
url_type: data.url_type || 'inline',
|
url_type: data.url_type || 'inline',
|
||||||
background: data.background || null,
|
background: data.background || null,
|
||||||
|
capsule: $A.isJson(data.capsule) ? data.capsule : {},
|
||||||
transparent: typeof data.transparent == 'boolean' ? data.transparent : false,
|
transparent: typeof data.transparent == 'boolean' ? data.transparent : false,
|
||||||
disable_scope_css: typeof data.disable_scope_css == 'boolean' ? data.disable_scope_css : false,
|
disable_scope_css: typeof data.disable_scope_css == 'boolean' ? data.disable_scope_css : false,
|
||||||
auto_dark_theme: typeof data.auto_dark_theme == 'boolean' ? data.auto_dark_theme : true,
|
auto_dark_theme: typeof data.auto_dark_theme == 'boolean' ? data.auto_dark_theme : true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user