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> <template>
<button class="magic-ui-button"> <button class="magic-ui-button">
<slot> <slot>
<magic-ui-text :config="textConfig"></magic-ui-text> <p>{{ config?.text || '' }}</p>
</slot> </slot>
</button> </button>
</template> </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'; import useApp from '../../useApp';
interface ButtonSchema extends MComponent {
type: 'button';
text: string;
}
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
config: MComponent; config: ButtonSchema;
model?: any; model?: any;
}>(), }>(),
{ {
@ -22,11 +26,6 @@ const props = withDefaults(
}, },
); );
const textConfig = computed(() => ({
type: 'text',
text: props.config?.text || '',
}));
useApp({ useApp({
config: props.config, config: props.config,
methods: {}, methods: {},

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,11 @@
<template> <template>
<div <MContainer class="magic-ui-page-fragment" :config="config"></MContainer>
: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>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, inject } from 'vue';
import Core from '@tmagic/core';
import type { MPageFragment } from '@tmagic/schema'; import type { MPageFragment } from '@tmagic/schema';
import MComponent from '../../Component.vue'; import MContainer from '../../container';
import useApp from '../../useApp'; import useApp from '../../useApp';
const props = withDefaults( 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({ useApp({
config: props.config, config: props.config,
methods: {}, methods: {},

View File

@ -1,23 +1,11 @@
<template> <template>
<div <MContainer class="magic-ui-page" :config="config"></MContainer>
: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>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, inject } from 'vue';
import Core from '@tmagic/core';
import type { MPage } from '@tmagic/schema'; import type { MPage } from '@tmagic/schema';
import MComponent from '../../Component.vue'; import MContainer from '../../container';
import useApp from '../../useApp'; import useApp from '../../useApp';
const props = withDefaults( 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 = () => { const refresh = () => {
window.location.reload(); window.location.reload();
}; };

View File

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

View File

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