feat(vue-components): 添加页面片容器id prop

This commit is contained in:
roymondchen 2025-07-15 15:31:51 +08:00
parent 1736d495fd
commit a43825caa2
30 changed files with 285 additions and 1284 deletions

View File

@ -68,7 +68,7 @@
"prettier": "^3.5.3",
"recast": "^0.23.11",
"rimraf": "^3.0.2",
"rollup": "^4.44.1",
"rollup": "^4.45.0",
"rollup-plugin-dts": "^6.2.1",
"semver": "^7.7.1",
"serialize-javascript": "^6.0.2",

1398
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,6 @@ packages:
catalog:
vue: ^3.5.17
'@vue/compiler-sfc': ^3.5.17
vite: ^7.0.0
vite: ^7.0.3
typescript: "^5.8.3"

View File

@ -1,5 +1,5 @@
{
"version": "0.1.1",
"version": "0.2.0",
"name": "@tmagic/react-runtime-help",
"type": "module",
"sideEffects": false,
@ -31,8 +31,8 @@
},
"peerDependencies": {
"lodash-es": "^4.17.21",
"@tmagic/core": ">=1.5.0",
"@tmagic/stage": ">=1.5.0",
"@tmagic/core": ">=1.6.0-beta.0",
"@tmagic/stage": ">=1.6.0-beta.0",
"react": ">=18.3.1",
"typescript": "catalog:"
},

View File

@ -20,7 +20,7 @@
},
"dependencies": {
"@tmagic/core": "1.6.0-beta.0",
"@tmagic/react-runtime-help": "0.1.1",
"@tmagic/react-runtime-help": "0.2.0",
"@tmagic/stage": "1.6.0-beta.0",
"axios": "^1.10.0",
"react": "^18.3.1",

View File

@ -1,5 +1,5 @@
{
"version": "1.5.18",
"version": "1.6.0-beta.0",
"name": "@tmagic/ui",
"type": "module",
"main": "dist/tmagic-ui.js",

View File

@ -1,5 +1,5 @@
{
"version": "1.1.5",
"version": "1.2.1",
"name": "@tmagic/vue-runtime-help",
"type": "module",
"sideEffects": false,
@ -30,8 +30,8 @@
"vue-demi": "^0.14.10"
},
"peerDependencies": {
"@tmagic/core": ">=1.5.0",
"@tmagic/stage": ">=1.5.0",
"@tmagic/core": ">=1.6.0-beta.0",
"@tmagic/stage": ">=1.6.0-beta.0",
"@vue/composition-api": ">=1.7.2",
"typescript": "catalog:",
"vue": ">=2.6.0 || >=3.5.0"

View File

@ -21,20 +21,20 @@
"dependencies": {
"@tmagic/core": "1.6.0-beta.0",
"@tmagic/stage": "1.6.0-beta.0",
"@tmagic/vue-runtime-help": "^1.1.5",
"@tmagic/vue-runtime-help": "^1.2.0",
"axios": "^1.10.0",
"vue": "^2.7.16"
},
"devDependencies": {
"@tmagic/cli": "1.6.0-beta.0",
"@types/events": "^3.0.3",
"rollup": "^4.44.1",
"rollup": "^4.45.0",
"rollup-plugin-external-globals": "^0.13.0",
"sass": "^1.89.2",
"terser": "^5.43.1",
"vite": "catalog:",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue2": "^2.3.1",
"vue-template-compiler": "^2.7.4"
"@vitejs/plugin-legacy": "^7.0.0",
"@vitejs/plugin-vue2": "^2.3.3",
"vue-template-compiler": "^2.7.16"
}
}

View File

@ -21,7 +21,7 @@
"dependencies": {
"@tmagic/core": "1.6.0-beta.0",
"@tmagic/stage": "1.6.0-beta.0",
"@tmagic/vue-runtime-help": "^1.1.5",
"@tmagic/vue-runtime-help": "^1.2.0",
"axios": "^1.10.0",
"vue": "catalog:"
},
@ -32,7 +32,7 @@
"@vitejs/plugin-vue": "^6.0.0",
"@vitejs/plugin-vue-jsx": "^5.0.1",
"@vue/compiler-sfc": "catalog:",
"rollup": "^4.44.1",
"rollup": "^4.45.0",
"rollup-plugin-external-globals": "^0.13.0",
"sass": "^1.89.2",
"terser": "^ 5.43.1",

View File

@ -16,9 +16,10 @@
* limitations under the License.
*/
import { createApp, defineAsyncComponent } from 'vue';
import { createApp, defineAsyncComponent, resolveDirective, withDirectives } from 'vue';
import TMagicApp, { DataSourceManager, DeepObservedData, getUrlParam, registerDataSourceOnDemand } from '@tmagic/core';
import { UserRenderFunctionOptions } from '@tmagic/vue-runtime-help';
import components from '../.tmagic/async-comp-entry';
import asyncDataSources from '../.tmagic/async-datasource-entry';
@ -56,6 +57,32 @@ Object.values(plugins).forEach((plugin: any) => {
vueApp.use(plugin, { app });
});
vueApp.provide(
'userRender',
({ h, type, props = {}, attrs = {}, style, className, on, directives = [] }: UserRenderFunctionOptions) => {
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);
},
);
registerDataSourceOnDemand(dsl, asyncDataSources).then((dataSources) => {
Object.entries(dataSources).forEach(([type, ds]: [string, any]) => {
DataSourceManager.register(type, ds);

View File

@ -1,5 +1,5 @@
{
"version": "0.1.2",
"version": "0.2.0",
"name": "@tmagic/vue-button",
"type": "module",
"main": "src/index.ts",

View File

@ -29,6 +29,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),

View File

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

View File

@ -1,4 +1,4 @@
import { defineComponent, h, inject, type PropType, provide, resolveDirective, withDirectives } from 'vue-demi';
import { defineComponent, h, inject, type PropType, provide } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import { Id, IS_DSL_NODE_KEY, MComponent } from '@tmagic/core';
@ -21,12 +21,16 @@ export default defineComponent({
type: Array as PropType<Id[]>,
default: () => [],
},
pageFragmentContainerId: {
type: [String, Number] as PropType<Id>,
default: '',
},
},
setup(props) {
const userRender = inject<UserRenderFunction>(
'userRender',
({ h, type, props = {}, attrs = {}, style, className, on, directives = [] }) => {
({ h, type, props = {}, attrs = {}, style, className, on }) => {
const options: Record<string, any> = {
...props,
...attrs,
@ -38,14 +42,6 @@ export default defineComponent({
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);
},
);
@ -78,12 +74,14 @@ export default defineComponent({
containerIndex: props.index,
iteratorIndex: props.iteratorIndex,
iteratorContainerId: props.iteratorContainerId,
pageFragmentContainerId: props.pageFragmentContainerId,
},
attrs: {
'data-tmagic-id': props.config.id,
'data-tmagic-iterator-index': props.iteratorIndex.join(',') || undefined,
'data-tmagic-iterator-container-id': props.iteratorContainerId.join(',') || undefined,
'data-container-index': props.index,
'data-tmagic-container-index': props.index,
'data-tmagic-page-fragment-container-id': props.pageFragmentContainerId || undefined,
},
});
};

View File

@ -1,14 +1,15 @@
<template>
<div @click="clickHandler">
<slot>
<template v-for="(item, index) in config.items" :key="item.id">
<ItemComponent
:config="item"
:index="index"
:iterator-index="iteratorIndex"
:iterator-container-id="iteratorContainerId"
></ItemComponent>
</template>
<ItemComponent
v-for="(item, index) in config.items"
:key="item.id"
:config="item"
:index="index"
:iterator-index="iteratorIndex"
:iterator-container-id="iteratorContainerId"
:page-fragment-container-id="pageFragmentContainerId"
></ItemComponent>
</slot>
</div>
</template>
@ -44,6 +45,7 @@ export default defineComponent({
default: () => [],
},
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"name": "@tmagic/vue-img",
"type": "module",
"main": "src/index.ts",

View File

@ -26,6 +26,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),

View File

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

View File

@ -13,9 +13,8 @@
</template>
<script lang="ts">
import { computed, defineComponent, inject, type PropType, watch } from 'vue-demi';
import { computed, defineComponent, type PropType, watch } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import {
COMMON_EVENT_PREFIX,
type Id,
@ -23,7 +22,7 @@ import {
type MIteratorContainer,
type MNode,
} from '@tmagic/core';
import { registerNodeHooks, useNode } from '@tmagic/vue-runtime-help';
import { registerNodeHooks, useApp } from '@tmagic/vue-runtime-help';
import IteratorItem from './IteratorItem.vue';
@ -53,6 +52,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),
@ -60,8 +60,7 @@ export default defineComponent({
},
setup(props) {
const app = inject<TMagicApp>('app');
const node = useNode(props, app);
const { app, node } = useApp(props);
registerNodeHooks(node);
const configs = computed<IteratorItemSchema[]>(() => {
@ -104,11 +103,11 @@ export default defineComponent({
return;
}
const iteratorContainerNode = app?.getNode<TMagicIteratorContainer>(
props.config.id,
props.iteratorContainerId,
props.iteratorIndex,
);
const iteratorContainerNode = app?.getNode<TMagicIteratorContainer>(props.config.id, {
iteratorContainerId: props.iteratorContainerId,
iteratorIndex: props.iteratorIndex,
pageFragmentContainerId: props.pageFragmentContainerId,
});
if (!iteratorContainerNode) {
return;

View File

@ -13,7 +13,7 @@
import { defineComponent, inject, type PropType } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import type { Id } from '@tmagic/core';
import { type Id } from '@tmagic/core';
import { useComponent, useComponentStatus } from '@tmagic/vue-runtime-help';
import { IteratorItemSchema } from './type';

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"name": "@tmagic/vue-overlay",
"type": "module",
"main": "src/index.ts",

View File

@ -27,6 +27,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"name": "@tmagic/vue-page-fragment-container",
"type": "module",
"main": "src/index.ts",

View File

@ -4,6 +4,7 @@
:is="containerComponent"
:iterator-index="iteratorIndex"
:iterator-container-id="iteratorContainerId"
:page-fragment-container-id="config.id"
:config="containerConfig"
:model="model"
></component>
@ -11,11 +12,18 @@
</template>
<script lang="ts">
import { computed, defineComponent, inject, type PropType } from 'vue-demi';
import { computed, defineComponent, type PropType, provide } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import { cloneDeep, type Id, IS_DSL_NODE_KEY, type MComponent, NodeType, traverseNode } from '@tmagic/core';
import { registerNodeHooks, useComponent, useNode } from '@tmagic/vue-runtime-help';
import {
cloneDeep,
type Id,
IS_DSL_NODE_KEY,
type MComponent,
NodeType,
PAGE_FRAGMENT_CONTAINER_ID_KEY,
traverseNode,
} from '@tmagic/core';
import { registerNodeHooks, useApp, useComponent, useDsl } from '@tmagic/vue-runtime-help';
export default defineComponent({
name: 'tmagic-page-fragment-container',
@ -28,6 +36,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),
@ -35,13 +44,14 @@ export default defineComponent({
},
setup(props) {
const app = inject<TMagicApp>('app');
const node = useNode(props, app);
provide(PAGE_FRAGMENT_CONTAINER_ID_KEY, props.config.id);
const { app, node } = useApp(props);
registerNodeHooks(node);
const containerComponent = useComponent({ componentType: 'container', app });
const fragment = computed(() => app?.dsl?.items?.find((page) => page.id === props.config.pageFragmentId));
const { pageConfig: fragment } = useDsl(app, props.config.id);
const containerConfig = computed(() => {
if (!fragment.value) return { items: [], id: '', type: NodeType.CONTAINER };

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"name": "@tmagic/vue-page-fragment",
"type": "module",
"main": "src/index.ts",

View File

@ -1,5 +1,5 @@
{
"version": "0.1.1",
"version": "0.2.1",
"name": "@tmagic/vue-page",
"type": "module",
"main": "src/index.ts",

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"name": "@tmagic/vue-qrcode",
"type": "module",
"main": "src/index.ts",

View File

@ -27,6 +27,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),

View File

@ -1,5 +1,5 @@
{
"version": "0.1.1",
"version": "0.2.1",
"name": "@tmagic/vue-text",
"type": "module",
"main": "src/index.ts",

View File

@ -26,6 +26,7 @@ export default defineComponent({
iteratorIndex: Array as PropType<number[]>,
iteratorContainerId: Array as PropType<Id[]>,
containerIndex: Number,
pageFragmentContainerId: [String, Number] as PropType<Id>,
model: {
type: Object,
default: () => ({}),