refactor(ui): 完善props定义,优化冗余代码

This commit is contained in:
roymondchen 2024-05-15 20:23:51 +08:00
parent 901fe4dd94
commit 7a13cd851b
12 changed files with 144 additions and 218 deletions

View File

@ -1,46 +0,0 @@
<template>
<component
v-if="display"
ref="component"
:is="tagName"
:id="config.id"
:class="`magic-ui-component${config.className ? ` ${config.className}` : ''}`"
:style="style"
:config="config"
></component>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import Core from '@tmagic/core';
import { toLine } from '@tmagic/utils';
const props = withDefaults(
defineProps<{
config: Record<string, any>;
model?: any;
}>(),
{
config: () => ({}),
model: () => ({}),
},
);
const app: Core | undefined = inject('app');
const tagName = computed(() => `magic-ui-${toLine(props.config.type)}`);
const style = computed(() => app?.transformStyle(props.config.style));
const display = computed(() => {
if (props.config.visible === false) return false;
if (props.config.condResult === false) return false;
const displayCfg = props.config?.display;
if (typeof displayCfg === 'function') {
return displayCfg(app);
}
return displayCfg !== false;
});
</script>

View File

@ -1,20 +1,24 @@
<template>
<button class="magic-ui-button">
<slot>
<magic-ui-text :config="textConfig"></magic-ui-text>
<p>{{ config?.text || '' }}</p>
</slot>
</button>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { MComponent } from '@tmagic/schema';
<script lang="ts" setup>
import type { MComponent } from '@tmagic/schema';
import useApp from '../../useApp';
interface ButtonSchema extends MComponent {
type: 'button';
text: string;
}
const props = withDefaults(
defineProps<{
config: MComponent;
config: ButtonSchema;
model?: any;
}>(),
{
@ -22,11 +26,6 @@ const props = withDefaults(
},
);
const textConfig = computed(() => ({
type: 'text',
text: props.config?.text || '',
}));
useApp({
config: props.config,
methods: {},

View File

@ -1,24 +1,28 @@
<template>
<div
v-if="display()"
:id="`${config.id || ''}`"
:class="`magic-ui-container magic-layout-${config.layout}${config.className ? ` ${config.className}` : ''}`"
:style="style"
>
<slot></slot>
<MComponent v-for="item in config.items" :key="item.id" :config="item"></MComponent>
<div v-if="display(config)" :id="`${config.id}`" :class="className" :style="style">
<slot>
<template v-for="item in config.items">
<component
v-if="display(item)"
:key="item.id"
:is="`magic-ui-${toLine(item.type)}`"
:id="item.id"
:class="`${item.className || ''}`"
:style="app?.transformStyle(item.style || {})"
:config="item"
></component>
</template>
</slot>
</div>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import { computed } from 'vue';
import Core from '@tmagic/core';
import type { MContainer } from '@tmagic/schema';
import { toLine } from '@tmagic/utils';
import MComponent from '../../Component.vue';
import useApp from '../../useApp';
import useCommonMethod from '../../useCommonMethod';
const props = withDefaults(
defineProps<{
@ -30,23 +34,19 @@ const props = withDefaults(
},
);
const app: Core | undefined = inject('app');
const style = computed(() => app?.transformStyle(props.config.style || {}));
const display = () => {
const displayCfg = props.config?.display;
if (typeof displayCfg === 'function') {
return displayCfg(app);
}
return displayCfg !== false;
};
useApp({
const { style, display, app } = useApp({
config: props.config,
methods: {
...useCommonMethod(props),
},
methods: {},
});
const className = computed(() => {
const list = ['magic-ui-container'];
if (props.config.layout) {
list.push(`magic-layout-${props.config.layout}`);
}
if (props.config.className) {
list.push(props.config.className);
}
return list.join(' ');
});
</script>

View File

@ -1,14 +1,21 @@
<template>
<img class="magic-ui-img" :src="config.src" @click="clickHandler" />
</template>
<script lang="ts" setup>
import { MComponent } from '@tmagic/schema';
import type { MComponent } from '@tmagic/schema';
import useApp from '../../useApp';
interface ImgSchema extends MComponent {
type: 'img';
src: string;
url: string;
}
const props = withDefaults(
defineProps<{
config: MComponent;
config: ImgSchema;
model?: any;
}>(),
{

View File

@ -1,14 +1,13 @@
<template>
<div class="magic-ui-iterator-container" :id="`${config.id || ''}`" :style="style">
<div class="magic-ui-iterator-container">
<Container v-for="(item, index) in configs" :key="index" :config="item"></Container>
</div>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import { computed } from 'vue';
import Core from '@tmagic/core';
import type { MContainer } from '@tmagic/schema';
import { type MContainer, NodeType } from '@tmagic/schema';
import Container from '../../container';
import useApp from '../../useApp';
@ -31,9 +30,10 @@ const props = withDefaults(
},
);
const app: Core | undefined = inject('app');
const style = computed(() => app?.transformStyle(props.config.style || {}));
const { app } = useApp({
config: props.config,
methods: {},
});
const configs = computed(() => {
const { iteratorData = [] } = props.config;
@ -47,6 +47,7 @@ const configs = computed(() => {
app?.dataSourceManager?.compliedIteratorItems(itemData, props.config.items, props.config.dsField) ??
props.config.items,
id: '',
type: NodeType.CONTAINER,
style: {
...props.config.itemConfig.style,
position: 'relative',
@ -55,9 +56,4 @@ const configs = computed(() => {
},
}));
});
useApp({
config: props.config,
methods: {},
});
</script>

View File

@ -3,17 +3,21 @@
<slot></slot>
</magic-ui-container>
</template>
<script lang="ts" setup>
import { inject, ref } from 'vue';
import Core from '@tmagic/core';
import type { MComponent, MNode } from '@tmagic/schema';
<script lang="ts" setup>
import { ref } from 'vue';
import type { MContainer, MNode } from '@tmagic/schema';
import useApp from '../../useApp';
interface OverlaySchema extends MContainer {
type: 'overlay';
}
const props = withDefaults(
defineProps<{
config: MComponent;
config: OverlaySchema;
model?: any;
}>(),
{
@ -22,36 +26,26 @@ const props = withDefaults(
);
const visible = ref(false);
const app: Core | undefined = inject('app');
const node = app?.page?.getNode(props.config.id);
const openOverlay = () => {
visible.value = true;
if (app) {
app.emit('overlay:open', node);
}
};
const closeOverlay = () => {
visible.value = false;
if (app) {
app.emit('overlay:close', node);
}
};
const { app, node } = useApp({
config: props.config,
methods: {
openOverlay() {
visible.value = true;
app?.emit('overlay:open', node);
},
closeOverlay() {
visible.value = false;
app?.emit('overlay:close', node);
},
},
});
app?.page?.on('editor:select', (info, path) => {
if (path.find((node: MNode) => node.id === props.config.id)) {
openOverlay();
node?.instance.openOverlay();
} else {
closeOverlay();
node?.instance.closeOverlay();
}
});
useApp({
config: props.config,
methods: {
openOverlay,
closeOverlay,
},
});
</script>

View File

@ -5,10 +5,9 @@
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import { computed } from 'vue';
import Core from '@tmagic/core';
import { MComponent, MNode } from '@tmagic/schema';
import { type MComponent, type MNode, NodeType } from '@tmagic/schema';
import Container from '../../container';
import useApp from '../../useApp';
@ -23,32 +22,43 @@ const props = withDefaults(
},
);
const app: Core | undefined = inject('app');
const { app } = useApp({
config: props.config,
methods: {},
});
const fragment = computed(() => app?.dsl?.items?.find((page) => page.id === props.config.pageFragmentId));
const containerConfig = computed(() => {
if (!fragment.value) return { items: [] };
if (!fragment.value) return { items: [], id: '', type: NodeType.CONTAINER };
const { id, type, items, ...others } = fragment.value;
const itemsWithoutId = items.map((item: MNode) => {
const { id, ...otherConfig } = item;
return otherConfig;
return {
id: '',
...otherConfig,
};
});
if (app?.platform === 'editor') {
return {
...others,
items: itemsWithoutId,
id: '',
type: NodeType.CONTAINER,
};
}
return {
...others,
items,
id: '',
type: NodeType.CONTAINER,
};
});
useApp({
config: props.config,
methods: {},
});
</script>
<style scoped>
.in-editor .magic-ui-page-fragment-container {
min-width: 100px;

View File

@ -1,23 +1,11 @@
<template>
<div
:id="`${config.id || ''}`"
:class="`magic-ui-page-fragment magic-ui-container magic-layout-${config.layout}${
config.className ? ` ${config.className}` : ''
}`"
:style="style"
>
<slot></slot>
<MComponent v-for="item in config.items" :key="item.id" :config="item"></MComponent>
</div>
<MContainer class="magic-ui-page-fragment" :config="config"></MContainer>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import Core from '@tmagic/core';
import type { MPageFragment } from '@tmagic/schema';
import MComponent from '../../Component.vue';
import MContainer from '../../container';
import useApp from '../../useApp';
const props = withDefaults(
@ -30,10 +18,6 @@ const props = withDefaults(
},
);
const app: Core | undefined = inject('app');
const style = computed(() => app?.transformStyle(props.config.style || {}));
useApp({
config: props.config,
methods: {},

View File

@ -1,23 +1,11 @@
<template>
<div
:id="`${config.id || ''}`"
:class="`magic-ui-page magic-ui-container magic-layout-${config.layout}${
config.className ? ` ${config.className}` : ''
}`"
:style="style"
>
<slot></slot>
<MComponent v-for="item in config.items" :key="item.id" :config="item"></MComponent>
</div>
<MContainer class="magic-ui-page" :config="config"></MContainer>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import Core from '@tmagic/core';
import type { MPage } from '@tmagic/schema';
import MComponent from '../../Component.vue';
import MContainer from '../../container';
import useApp from '../../useApp';
const props = withDefaults(
@ -30,10 +18,6 @@ const props = withDefaults(
},
);
const app: Core | undefined = inject('app');
const style = computed(() => app?.transformStyle(props.config.style || {}));
const refresh = () => {
window.location.reload();
};

View File

@ -3,13 +3,13 @@
</template>
<script lang="ts" setup>
import { MComponent } from '@tmagic/schema';
import type { MComponent } from '@tmagic/schema';
import useApp from '../../useApp';
const props = withDefaults(
defineProps<{
config: MComponent;
config: MComponent & { type: 'text'; text: string };
model?: any;
}>(),
{

View File

@ -16,36 +16,60 @@
* limitations under the License.
*/
import { inject, onBeforeUnmount, onMounted } from 'vue';
import { computed, inject, onBeforeUnmount, onMounted } from 'vue';
import Core from '@tmagic/core';
import type { MComponent } from '@tmagic/schema';
import type { MNode } from '@tmagic/schema';
interface UseAppOptions {
config: MComponent;
interface UseAppOptions<T extends MNode = MNode> {
config: T;
methods?: {
[key: string]: Function;
};
}
export default ({ config, methods }: UseAppOptions) => {
export default ({ methods, config }: UseAppOptions) => {
const app: Core | undefined = inject('app');
const node = app?.page?.getNode(config.id);
const node = app?.page?.getNode(config.id || '');
const style = computed(() => (app ? app.transformStyle(config.style || {}) : config.style));
const emitData = {
config,
...methods,
};
node?.emit('created', emitData);
const display = <T extends MNode>(config: T) => {
if (config.visible === false) return false;
if (config.condResult === false) return false;
onMounted(() => {
node?.emit('mounted', emitData);
});
const displayCfg = config.display;
onBeforeUnmount(() => {
node?.emit('destroy', emitData);
});
if (typeof displayCfg === 'function') {
return displayCfg(app);
}
return app;
return displayCfg !== false;
};
if (node) {
node.emit('created', emitData);
onMounted(() => {
node.emit('mounted', emitData);
});
onBeforeUnmount(() => {
node.emit('destroy', emitData);
});
}
return {
app,
node,
style,
display,
};
};

View File

@ -1,26 +0,0 @@
/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default (props: any) => ({
show: () => {
props.config.style.display = 'initial';
},
hide: () => {
props.config.style.display = 'none';
},
});