1
0
mirror of synced 2025-12-07 14:23:37 +08:00

feat(vue-components,react-components): 增加点击事件,使用组件状态hook

This commit is contained in:
roymondchen
2025-03-06 20:29:38 +08:00
parent 8d0040da53
commit 0736646c63
60 changed files with 594 additions and 378 deletions

View File

@@ -1,5 +1,5 @@
{
"version": "1.0.0",
"version": "1.1.0",
"name": "@tmagic/vue-container",
"type": "module",
"main": "src/index.ts",

View File

@@ -1,13 +1,15 @@
import { defineComponent, h, inject, type PropType } from 'vue-demi';
import { defineComponent, h, inject, type PropType, provide, resolveDirective, withDirectives } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import { Id, IS_DSL_NODE_KEY, MComponent, toLine } from '@tmagic/core';
import { useComponent, type UserRenderFunction } from '@tmagic/vue-runtime-help';
import { Id, IS_DSL_NODE_KEY, MComponent } from '@tmagic/core';
import { useComponent, useComponentStatus, useNode, type UserRenderFunction } from '@tmagic/vue-runtime-help';
export default defineComponent({
name: 'tmagic-container-item',
props: {
config: {
type: Object as PropType<MComponent>,
type: Object as PropType<Omit<MComponent, 'id'>>,
required: true,
},
index: Number,
@@ -22,21 +24,55 @@ export default defineComponent({
},
setup(props) {
const userRender = inject<UserRenderFunction>('userRender', ({ h, type, props, attrs, style, className }) =>
h(type, { ...props, ...attrs, style, class: className }),
const userRender = inject<UserRenderFunction>(
'userRender',
({ h, type, props = {}, attrs = {}, style, className, on, directives = [] }) => {
const options: Record<string, any> = {
...props,
...attrs,
style,
class: className,
};
if (on) {
for (const [key, handler] of Object.entries(on)) {
options[`on${key[0].toLocaleUpperCase()}${key.substring(1)}`] = handler;
}
}
if (directives.length) {
return withDirectives(
h(type, options),
directives.map((directive) => [resolveDirective(directive.name), directive.value, directive.modifiers]),
);
}
return h(type, options);
},
);
const app = inject<TMagicApp>('app');
const node = useNode(props);
return () =>
userRender({
const componentStatusStore = useComponentStatus(props);
provide('componentStatusStore', componentStatusStore);
const { style, className } = componentStatusStore;
return () => {
if (props.config.visible === false) return null;
if (props.config.condResult === false) return null;
if (typeof props.config.display === 'function' && props.config.display({ app, node }) === false) {
return null;
}
return userRender({
h,
config: props.config,
type: useComponent({ componentType: props.config.type, app }),
style: app?.transformStyle(props.config.style || {}),
className: props.config.className
? `${props.config.className} magic-ui-${toLine(props.config.type)}`
: `magic-ui-${toLine(props.config.type)}`,
style: style.value,
className: className.value,
props: {
config: { ...props.config, [IS_DSL_NODE_KEY]: true },
containerIndex: props.index,
@@ -45,10 +81,11 @@ export default defineComponent({
},
attrs: {
'data-tmagic-id': props.config.id,
'data-tmagic-iterator-index': props.iteratorIndex,
'data-tmagic-iterator-container-id': props.iteratorContainerId,
'data-tmagic-iterator-index': props.iteratorIndex.join(',') || undefined,
'data-tmagic-iterator-container-id': props.iteratorContainerId.join(',') || undefined,
'data-container-index': props.index,
},
});
};
},
});

View File

@@ -1,10 +1,8 @@
<template>
<div v-if="display(config)" :class="className" :style="style">
<div @click="clickHandler">
<slot>
<template v-for="(item, index) in config.items">
<template v-for="(item, index) in config.items" :key="item.id">
<ItemComponent
v-if="display(item)"
:key="item.id"
:config="item"
:index="index"
:iterator-index="iteratorIndex"
@@ -16,11 +14,11 @@
</template>
<script lang="ts">
import { computed, defineComponent, type PropType } from 'vue-demi';
import { defineComponent, inject, type PropType } from 'vue-demi';
import type { Id, MContainer } from '@tmagic/core';
import { IS_DSL_NODE_KEY } from '@tmagic/core';
import { useApp } from '@tmagic/vue-runtime-help';
import type TMagicApp from '@tmagic/core';
import { COMMON_EVENT_PREFIX, type Id, type MContainer } from '@tmagic/core';
import { registerNodeHooks, useNode } from '@tmagic/vue-runtime-help';
import ItemComponent from './Component';
@@ -45,6 +43,7 @@ export default defineComponent({
type: Array as PropType<Id[]>,
default: () => [],
},
containerIndex: Number,
model: {
type: Object,
default: () => ({}),
@@ -54,37 +53,18 @@ export default defineComponent({
components: { ItemComponent },
setup(props) {
const { display, app } = useApp({
config: props.config,
iteratorContainerId: props.iteratorContainerId,
iteratorIndex: props.iteratorIndex,
methods: {},
});
const app = inject<TMagicApp>('app');
const node = useNode(props, app);
registerNodeHooks(node);
const className = computed(() => {
const list = ['magic-ui-container'];
if (props.config.layout) {
list.push(`magic-layout-${props.config.layout}`);
const clickHandler = () => {
if (app && node) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
if (props.config.className) {
list.push(props.config.className);
}
return list.join(' ');
});
const style = computed(() => {
if (props.config[IS_DSL_NODE_KEY]) {
return {};
}
return app?.transformStyle(props.config.style || {});
});
};
return {
app,
className,
style,
display,
clickHandler,
};
},
});

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};