perf: 优化应用商城

- 支持 background 参数
- iframe 模式添加安全距离
- iframe 支持 dootask/tools
This commit is contained in:
kuaifan 2025-07-04 15:31:34 +08:00
parent 958ef80602
commit a10bc74de1
4 changed files with 65 additions and 6 deletions

View File

@ -3,7 +3,8 @@
ref="iframe" ref="iframe"
class="micro-app-iframe" class="micro-app-iframe"
:src="src" :src="src"
sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"/> sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox">
</iframe>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -11,6 +12,8 @@
border: none; border: none;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding-top: var(--status-bar-height);
padding-bottom: var(--navigation-bar-height);
} }
</style> </style>
<script> <script>
@ -25,6 +28,10 @@ export default {
type: String, type: String,
default: '' default: ''
}, },
data: {
type: Object,
default: null
}
}, },
data() { data() {
@ -34,17 +41,22 @@ export default {
}, },
mounted() { mounted() {
this.injectMicroApp()
this.$refs.iframe.addEventListener('load', this.handleLoad.bind(this)) this.$refs.iframe.addEventListener('load', this.handleLoad.bind(this))
this.$refs.iframe.addEventListener('error', this.handleError.bind(this)) this.$refs.iframe.addEventListener('error', this.handleError.bind(this))
}, },
beforeDestroy() { beforeDestroy() {
this.cleanupMicroApp()
this.$refs.iframe.removeEventListener('load', this.handleLoad.bind(this)) this.$refs.iframe.removeEventListener('load', this.handleLoad.bind(this))
this.$refs.iframe.removeEventListener('error', this.handleError.bind(this)) this.$refs.iframe.removeEventListener('error', this.handleError.bind(this))
}, },
methods: { methods: {
// iframe
handleLoad(e) { handleLoad(e) {
this.injectMicroApp()
this.$emit('mounted', { this.$emit('mounted', {
...e, ...e,
detail: { detail: {
@ -53,6 +65,7 @@ export default {
}) })
}, },
// iframe
handleError(e) { handleError(e) {
this.$emit('error', { this.$emit('error', {
...e, ...e,
@ -61,7 +74,33 @@ export default {
error: e, error: e,
} }
}) })
},
// microApp iframe
injectMicroApp() {
try {
const iframeWindow = this.$refs.iframe.contentWindow
if (iframeWindow && this.data) {
iframeWindow.microApp = {
getData: () => this.data
} }
} }
} catch (error) {
console.error('Failed to inject microApp object:', error)
}
},
// microApp
cleanupMicroApp() {
try {
const iframeWindow = this.$refs.iframe.contentWindow
if (iframeWindow && iframeWindow.microApp) {
delete iframeWindow.microApp
}
} catch (error) {
console.error('Failed to cleanup microApp object:', error)
}
},
}
} }
</script> </script>

View File

@ -6,6 +6,7 @@
v-model="app.isOpen" v-model="app.isOpen"
:ref="`ref-${app.name}`" :ref="`ref-${app.name}`"
:size="1200" :size="1200"
:background="app.background"
:transparent="app.transparent" :transparent="app.transparent"
:autoDarkTheme="app.auto_dark_theme" :autoDarkTheme="app.auto_dark_theme"
:beforeClose="async () => { await onBeforeClose(app.name) }"> :beforeClose="async () => { await onBeforeClose(app.name) }">
@ -13,6 +14,7 @@
v-if="app.url_type === 'iframe' && app.isOpen && app.url" v-if="app.url_type === 'iframe' && app.isOpen && app.url"
:name="app.name" :name="app.name"
:url="app.url" :url="app.url"
:data="appData(app.name)"
@mounted="mounted" @mounted="mounted"
@error="error"/> @error="error"/>
<micro-app <micro-app
@ -206,6 +208,10 @@ export default {
props: { props: {
...app.props, ...app.props,
name: app.name,
url: app.url,
urlType: app.url_type,
userId: this.userId, userId: this.userId,
userToken: this.userToken, userToken: this.userToken,
userInfo: this.userInfo, userInfo: this.userInfo,

View File

@ -20,7 +20,7 @@
:reverse="true" :reverse="true"
:beforeResize="beforeResize" :beforeResize="beforeResize"
@on-change="onChangeResize"/> @on-change="onChangeResize"/>
<div ref="body" class="micro-modal-body"> <div ref="body" class="micro-modal-body" :style="bodyStyle">
<slot></slot> <slot></slot>
</div> </div>
</div> </div>
@ -50,6 +50,9 @@ export default {
type: Number, type: Number,
default: 300 default: 300
}, },
background: {
default: null
},
transparent: { transparent: {
type: Boolean, type: Boolean,
default: false default: false
@ -81,6 +84,15 @@ export default {
} }
return ['micro-modal-fade', 'micro-modal-slide'] return ['micro-modal-fade', 'micro-modal-slide']
}, },
bodyStyle() {
const styleObject = {}
if ($A.isJson(this.background)) {
styleObject.background = this.background
} else if (this.background) {
styleObject.backgroundColor = this.background;
}
return styleObject;
},
maskStyle({zIndex}) { maskStyle({zIndex}) {
return {zIndex} return {zIndex}
}, },

View File

@ -4665,7 +4665,8 @@ export default {
* - id 应用ID必须 * - id 应用ID必须
* - name 应用名称必须 * - name 应用名称必须
* - url 应用地址必须 * - url 应用地址必须
* - url_type 地址类型 * - url_type 地址类型可选
* - background 背景颜色可选
* - transparent 是否透明模式 (true/false)默认 false * - transparent 是否透明模式 (true/false)默认 false
* - disable_scope_css 是否禁用样式隔离 (true/false)默认 false * - disable_scope_css 是否禁用样式隔离 (true/false)默认 false
* - auto_dark_theme 是否自动适配深色主题 (true/false)默认 true * - auto_dark_theme 是否自动适配深色主题 (true/false)默认 true
@ -4695,6 +4696,7 @@ export default {
name: data.name, name: data.name,
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,
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,