feat(runtime): 支持页面切换

This commit is contained in:
roymondchen 2025-02-26 15:20:32 +08:00
parent 6d2b9d5f21
commit 4026c0c305
20 changed files with 172 additions and 109 deletions

View File

@ -64,6 +64,21 @@ const dsl: MApp = {
},
params: [],
},
code_6778: {
name: 'toOtherPage',
desc: '',
timing: '',
params: [
{
name: 'pageId',
extra: '',
type: '',
},
],
content: ({ app, params }) => {
app.setPage(params.pageId);
},
},
},
items: [
{
@ -250,6 +265,37 @@ const dsl: MApp = {
created: [],
displayConds: [],
},
{
id: 'button_1cb163ad',
text: '前往page2',
multiple: true,
style: {
width: '270',
height: '37.5',
border: 0,
backgroundColor: '#fb6f00',
position: 'absolute',
left: 56,
top: 266,
},
type: 'button',
name: '按钮',
events: [
{
name: 'magic:common:events:click',
actions: [
{
actionType: ActionType.CODE,
codeId: 'code_6778',
params: {
pageId: 'page_171ff161',
},
},
],
},
],
displayConds: [],
},
{
type: 'overlay',
id: 'overlay_2159',
@ -376,6 +422,53 @@ const dsl: MApp = {
},
],
},
{
id: 'page_171ff161',
items: [
{
id: 'button_80ca1076',
text: '返回',
multiple: true,
style: {
width: '270',
height: '37.5',
border: 0,
backgroundColor: '#fb6f00',
position: 'absolute',
left: 48,
top: 297,
},
type: 'button',
name: '按钮',
events: [
{
name: 'magic:common:events:click',
actions: [
{
actionType: ActionType.CODE,
codeId: 'code_6778',
params: {
pageId: 'page_299',
},
},
],
},
],
displayConds: [],
},
],
style: {
width: '100%',
height: '100%',
position: 'relative',
top: 0,
left: 0,
},
type: NodeType.PAGE,
name: 'page2',
title: '',
layout: 'absolute',
},
],
dataSources: [
{

View File

@ -263,7 +263,7 @@ const moveableOptions = (config?: CustomizeMoveableOptionsCallbackConfig): Movea
const save = () => {
localStorage.setItem(
'magicDSL',
'magicDSL2',
serialize(toRaw(value.value), {
space: 2,
unsafe: true,
@ -290,7 +290,7 @@ asyncLoadJs(`${VITE_ENTRY_PATH}/ds-value/index.umd.cjs`).then(() => {
try {
// eslint-disable-next-line no-eval
const magicDSL = eval(`(${localStorage.getItem('magicDSL')})`);
const magicDSL = eval(`(${localStorage.getItem('magicDSL2')})`);
if (!magicDSL) {
save();
} else {

55
pnpm-lock.yaml generated
View File

@ -906,21 +906,12 @@ importers:
'@tmagic/core':
specifier: 1.5.9
version: 1.5.9(typescript@5.7.3)
'@tmagic/data-source':
specifier: 1.5.9
version: 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
'@tmagic/react-runtime-help':
specifier: 0.0.3
version: 0.0.3(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/data-source@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@tmagic/schema@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@tmagic/utils@1.5.9(@tmagic/schema@1.5.9(typescript@5.7.3))(typescript@5.7.3))(lodash-es@4.17.21)(react@18.3.1)(typescript@5.7.3)
'@tmagic/schema':
specifier: 1.5.9
version: 1.5.9(typescript@5.7.3)
specifier: 0.0.4
version: 0.0.4(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(lodash-es@4.17.21)(react@18.3.1)(typescript@5.7.3)
'@tmagic/stage':
specifier: 1.5.9
version: 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
'@tmagic/utils':
specifier: 1.5.9
version: 1.5.9(@tmagic/schema@1.5.9(typescript@5.7.3))(typescript@5.7.3)
axios:
specifier: ^0.25.0
version: 0.25.0
@ -1033,8 +1024,8 @@ importers:
specifier: 1.5.9
version: 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
'@tmagic/vue-runtime-help':
specifier: ^0.1.4
version: 0.1.5(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@2.7.16))(typescript@5.7.3)(vue@2.7.16)
specifier: ^1.0.0
version: 1.0.0(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@2.7.16))(typescript@5.7.3)(vue@2.7.16)
axios:
specifier: ^0.25.0
version: 0.25.0
@ -1082,13 +1073,13 @@ importers:
specifier: 1.5.9
version: 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
'@tmagic/vue-runtime-help':
specifier: ^0.1.4
version: 0.1.5(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@3.5.13(typescript@5.7.3)))(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
specifier: ^1.0.0
version: 1.0.0(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@3.5.13(typescript@5.7.3)))(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
axios:
specifier: ^0.25.0
version: 0.25.0
vue:
specifier: '>=3.5.0'
specifier: ^3.5.0
version: 3.5.13(typescript@5.7.3)
devDependencies:
'@tmagic/cli':
@ -2866,20 +2857,17 @@ packages:
typescript:
optional: true
'@tmagic/react-runtime-help@0.0.3':
resolution: {integrity: sha512-ZxoxTO+NEk8pVzgAysQW3B790rYY8HVXXE6JlhSZeF/P+vL9PWGZjZDImRiuHxR+EMLNq5lUrf5iWF9Tg4ho+w==}
'@tmagic/react-runtime-help@0.0.4':
resolution: {integrity: sha512-H6WnitSMQUjZ4ArkO/a70l0GIqmTP+n+416PIvbCEVaVb5M8cBk72h3rTvwVp3CGFptLo/OYooyw7hO1ofVmCw==}
engines: {node: '>=18'}
peerDependencies:
'@tmagic/core': ^1.5.0-beta.4
'@tmagic/data-source': ^1.5.0-beta.4
'@tmagic/schema': ^1.5.0-beta.4
'@tmagic/stage': ^1.5.0-beta.4
'@tmagic/utils': ^1.5.0-beta.4
'@tmagic/core': '>=1.5.0'
'@tmagic/stage': '>=1.5.0'
lodash-es: ^4.17.21
react: '>=18.3.1'
typescript: '*'
peerDependenciesMeta:
'@tmagic/schema':
'@tmagic/core':
optional: true
'@tmagic/stage':
optional: true
@ -2985,12 +2973,12 @@ packages:
typescript:
optional: true
'@tmagic/vue-runtime-help@0.1.5':
resolution: {integrity: sha512-cBKqJYCND8I3DiNz8ENHa0kER+5zeuWhGISimglCddGcrAcg9+eloXZnFA8p4c4VzOrM8tqw+30gYUKMVZJ/UQ==}
'@tmagic/vue-runtime-help@1.0.0':
resolution: {integrity: sha512-dRNW56m7t9e+fDHVOgONz8xBI60rgCY+gxekyVP3oBq0JU8Sviuv8KVhM2YiMiTja6C/xTwBENSQLocYLV2UOw==}
engines: {node: '>=18'}
peerDependencies:
'@tmagic/core': '>=1.5.0-beta.14'
'@tmagic/stage': '>=1.5.0-beta.14'
'@tmagic/core': '>=1.5.0'
'@tmagic/stage': '>=1.5.0'
'@vue/composition-api': '>=1.7.2'
typescript: '*'
vue: '>=2.6.0 || >=3.5.0'
@ -8450,15 +8438,12 @@ snapshots:
optionalDependencies:
typescript: 5.7.3
'@tmagic/react-runtime-help@0.0.3(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/data-source@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@tmagic/schema@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@tmagic/utils@1.5.9(@tmagic/schema@1.5.9(typescript@5.7.3))(typescript@5.7.3))(lodash-es@4.17.21)(react@18.3.1)(typescript@5.7.3)':
'@tmagic/react-runtime-help@0.0.4(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(lodash-es@4.17.21)(react@18.3.1)(typescript@5.7.3)':
dependencies:
'@tmagic/core': 1.5.9(typescript@5.7.3)
'@tmagic/data-source': 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
'@tmagic/utils': 1.5.9(@tmagic/schema@1.5.9(typescript@5.7.3))(typescript@5.7.3)
lodash-es: 4.17.21
react: 18.3.1
optionalDependencies:
'@tmagic/schema': 1.5.9(typescript@5.7.3)
'@tmagic/core': 1.5.9(typescript@5.7.3)
'@tmagic/stage': 1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3)
typescript: 5.7.3
@ -8576,7 +8561,7 @@ snapshots:
optionalDependencies:
typescript: 5.7.3
'@tmagic/vue-runtime-help@0.1.5(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@2.7.16))(typescript@5.7.3)(vue@2.7.16)':
'@tmagic/vue-runtime-help@1.0.0(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@2.7.16))(typescript@5.7.3)(vue@2.7.16)':
dependencies:
vue: 2.7.16
vue-demi: 0.14.10(@vue/composition-api@1.7.2(vue@2.7.16))(vue@2.7.16)
@ -8586,7 +8571,7 @@ snapshots:
'@vue/composition-api': 1.7.2(vue@2.7.16)
typescript: 5.7.3
'@tmagic/vue-runtime-help@0.1.5(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@3.5.13(typescript@5.7.3)))(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))':
'@tmagic/vue-runtime-help@1.0.0(@tmagic/core@1.5.9(typescript@5.7.3))(@tmagic/stage@1.5.9(@tmagic/core@1.5.9(typescript@5.7.3))(typescript@5.7.3))(@vue/composition-api@1.7.2(vue@3.5.13(typescript@5.7.3)))(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))':
dependencies:
vue: 3.5.13(typescript@5.7.3)
vue-demi: 0.14.10(@vue/composition-api@1.7.2(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))

View File

@ -1,5 +1,5 @@
{
"version": "0.0.3",
"version": "0.0.4",
"name": "@tmagic/react-runtime-help",
"type": "module",
"sideEffects": false,

View File

@ -6,9 +6,11 @@ import type TMagicApp from '@tmagic/core';
import { isPage, replaceChildNode } from '@tmagic/core';
export const useDsl = (app: TMagicApp | undefined) => {
if (!app?.page) return null;
const [pageConfig, setPageConfig] = useState(app?.page?.data);
const [pageConfig, setPageConfig] = useState(app.page.data);
app?.on('page-change', () => {
setPageConfig(app.page?.data);
});
const updateDataHandler = (nodes: MNode[], sourceId: string, event: ChangeEvent) => {
let config = pageConfig;
@ -16,14 +18,14 @@ export const useDsl = (app: TMagicApp | undefined) => {
if (isPage(node)) {
config = node;
} else {
replaceChildNode(node, [config]);
config && replaceChildNode(node, [config]);
}
});
setPageConfig(cloneDeep(config));
setTimeout(() => {
app.emit('replaced-node', {
app?.emit('replaced-node', {
...event,
nodes,
sourceId,
@ -32,10 +34,10 @@ export const useDsl = (app: TMagicApp | undefined) => {
};
useEffect(() => {
app.dataSourceManager?.on('update-data', updateDataHandler);
app?.dataSourceManager?.on('update-data', updateDataHandler);
return () => {
app.dataSourceManager?.off('update-data', updateDataHandler);
app?.dataSourceManager?.off('update-data', updateDataHandler);
};
}, []);

View File

@ -11,11 +11,11 @@ declare global {
}
}
export const useEditorDsl = (app: TMagicApp | undefined, renderDom: () => void) => {
export const useEditorDsl = (app: TMagicApp, renderDom: () => void) => {
let curPageId: Id = '';
const updateConfig = (root: MApp) => {
app?.setConfig(root, curPageId);
app.setConfig(root, curPageId);
renderDom();
};
@ -30,7 +30,7 @@ export const useEditorDsl = (app: TMagicApp | undefined, renderDom: () => void)
updatePageId(id: Id) {
curPageId = id;
app?.setPage(curPageId);
app.setPage(curPageId);
renderDom();
},

View File

@ -38,6 +38,7 @@ export default defineConfig({
{ find: /^@data-source/, replacement: path.join(__dirname, '../../packages/data-source/src') },
{ find: /^@tmagic\/data-source/, replacement: path.join(__dirname, '../../packages/data-source/src/index.ts') },
{ find: /^@tmagic\/dep/, replacement: path.join(__dirname, '../../packages/dep/src/index.ts') },
{ find: /^@tmagic\/react-runtime-help/, replacement: path.join(__dirname, '../react-runtime-help/src/index.ts') },
],
},

View File

@ -20,11 +20,8 @@
},
"dependencies": {
"@tmagic/core": "1.5.9",
"@tmagic/data-source": "1.5.9",
"@tmagic/react-runtime-help": "0.0.3",
"@tmagic/schema": "1.5.9",
"@tmagic/react-runtime-help": "0.0.4",
"@tmagic/stage": "1.5.9",
"@tmagic/utils": "1.5.9",
"axios": "^0.25.0",
"terser": "^5.31.6",
"react": "^18.3.1",

View File

@ -18,11 +18,9 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import Core from '@tmagic/core';
import { DataSourceManager, DeepObservedData } from '@tmagic/data-source';
import type { MApp } from '@tmagic/core';
import Core, { DataSourceManager, DeepObservedData, getUrlParam } from '@tmagic/core';
import { AppContent } from '@tmagic/react-runtime-help';
import type { MApp } from '@tmagic/schema';
import { getUrlParam } from '@tmagic/utils';
import components from '../.tmagic/comp-entry';
import dataSources from '../.tmagic/datasource-entry';

View File

@ -19,8 +19,8 @@
import React, { useContext } from 'react';
import type Core from '@tmagic/core';
import type { MPage } from '@tmagic/core';
import { AppContent } from '@tmagic/react-runtime-help';
import type { MPage } from '@tmagic/schema';
function App() {
const app = useContext<Core | undefined>(AppContent);

View File

@ -19,8 +19,7 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import Core from '@tmagic/core';
import { DataSourceManager, DeepObservedData } from '@tmagic/data-source';
import Core, { DataSourceManager, DeepObservedData } from '@tmagic/core';
import { AppContent, useEditorDsl } from '@tmagic/react-runtime-help';
import components from '../.tmagic/comp-entry';

View File

@ -1,5 +1,5 @@
{
"version": "0.1.5",
"version": "1.0.0",
"name": "@tmagic/vue-runtime-help",
"type": "module",
"sideEffects": false,

View File

@ -1,11 +1,21 @@
import { nextTick, onBeforeUnmount, reactive, ref } from 'vue-demi';
import { inject, nextTick, onBeforeUnmount, reactive, ref } from 'vue-demi';
import type TMagicCore from '@tmagic/core';
import type { ChangeEvent, MNode } from '@tmagic/core';
import { isPage, replaceChildNode } from '@tmagic/core';
export const useDsl = (app?: TMagicCore) => {
const pageConfig = ref(app?.page?.data || {});
export const useDsl = () => {
const app = inject<TMagicCore>('app');
if (!app) {
throw new Error('useDsl must be used after MagicApp is created');
}
const pageConfig = ref(app.page?.data || {});
app.on('page-change', () => {
pageConfig.value = app.page?.data || {};
});
const updateDataHandler = (nodes: MNode[], sourceId: string, changeEvent: ChangeEvent) => {
nodes.forEach((node) => {
@ -16,20 +26,21 @@ export const useDsl = (app?: TMagicCore) => {
}
});
if (!app) return;
nextTick(() => {
app.emit('replaced-node', { nodes, sourceId, ...changeEvent });
});
};
app?.dataSourceManager?.on('update-data', updateDataHandler);
if (app.dataSourceManager) {
app.dataSourceManager.on('update-data', updateDataHandler);
onBeforeUnmount(() => {
app?.dataSourceManager?.off('update-data', updateDataHandler);
});
onBeforeUnmount(() => {
app.dataSourceManager!.off('update-data', updateDataHandler);
});
}
return {
app,
pageConfig,
};
};

View File

@ -1,4 +1,4 @@
import { computed, nextTick, reactive, ref, watch } from 'vue-demi';
import { computed, inject, nextTick, reactive, ref, watch } from 'vue-demi';
import type TMagicApp from '@tmagic/core';
import type { Id, MApp, MNode } from '@tmagic/core';
@ -11,7 +11,9 @@ declare global {
}
}
export const useEditorDsl = (app: TMagicApp | undefined, win = window) => {
export const useEditorDsl = (win = window) => {
const app = inject<TMagicApp>('app');
const root = ref<MApp>();
const curPageId = ref<Id>();
const selectedId = ref<Id>();
@ -123,5 +125,6 @@ export const useEditorDsl = (app: TMagicApp | undefined, win = window) => {
return {
pageConfig,
app,
};
};

View File

@ -21,7 +21,7 @@
"dependencies": {
"@tmagic/core": "1.5.9",
"@tmagic/stage": "1.5.9",
"@tmagic/vue-runtime-help": "^0.1.4",
"@tmagic/vue-runtime-help": "^1.0.0",
"axios": "^0.25.0",
"terser": "^5.31.6",
"vue": "^2.7.16"

View File

@ -3,28 +3,17 @@
</template>
<script lang="ts">
import { defineComponent, inject } from 'vue';
import { defineComponent } from 'vue';
import type { Page } from '@tmagic/core';
import type TMagicApp from '@tmagic/core';
import { addParamToUrl } from '@tmagic/core';
import { useComponent, useDsl } from '@tmagic/vue-runtime-help';
export default defineComponent({
name: 'App',
setup() {
const app = inject<TMagicApp>('app');
const { pageConfig } = useDsl(app);
const { pageConfig } = useDsl();
const pageComponent = useComponent('page');
app?.on('page-change', (page?: Page) => {
if (!page) {
throw new Error(`页面不存在`);
}
addParamToUrl({ page: page.data.id }, window);
});
return {
pageComponent,
pageConfig,

View File

@ -3,15 +3,13 @@
</template>
<script lang="ts">
import { defineComponent, inject } from 'vue';
import { defineComponent } from 'vue';
import type TMagicApp from '@tmagic/core';
import { useComponent, useEditorDsl } from '@tmagic/vue-runtime-help';
export default defineComponent({
setup() {
const app = inject<TMagicApp>('app');
const { pageConfig } = useEditorDsl(app);
const { pageConfig } = useEditorDsl();
const pageComponent = useComponent('page');
return {

View File

@ -21,9 +21,9 @@
"dependencies": {
"@tmagic/core": "1.5.9",
"@tmagic/stage": "1.5.9",
"@tmagic/vue-runtime-help": "^0.1.4",
"@tmagic/vue-runtime-help": "^1.0.0",
"axios": "^0.25.0",
"vue": ">=3.5.0"
"vue": "^3.5.0"
},
"devDependencies": {
"@tmagic/cli": "1.5.9",

View File

@ -3,25 +3,16 @@
</template>
<script lang="ts" setup>
import { inject, reactive } from 'vue';
import { reactive } from 'vue';
import type { Id, MPage, Page } from '@tmagic/core';
import type TMagicApp from '@tmagic/core';
import { addParamToUrl, cloneDeep, DevtoolApi, getNodeInfo, replaceChildNode, setValueByKeyPath } from '@tmagic/core';
import type { Id, MPage } from '@tmagic/core';
import { cloneDeep, DevtoolApi, getNodeInfo, replaceChildNode, setValueByKeyPath } from '@tmagic/core';
import { useComponent, useDsl } from '@tmagic/vue-runtime-help';
const app = inject<TMagicApp>('app');
const { pageConfig } = useDsl(app);
const { pageConfig, app } = useDsl();
const pageComponent = useComponent('page');
app?.on('page-change', (page?: Page) => {
if (!page) {
throw new Error(`页面不存在`);
}
addParamToUrl({ page: page.data.id }, window);
});
if (import.meta.env.DEV && app) {
if (import.meta.env.DEV) {
app.devtools = new (class extends DevtoolApi {
public updateDsl(nodeId: Id, data: any, path: string) {
if (!app.dsl) {

View File

@ -3,12 +3,8 @@
</template>
<script lang="ts" setup>
import { inject } from 'vue';
import type TMagicApp from '@tmagic/core';
import { useComponent, useEditorDsl } from '@tmagic/vue-runtime-help';
const app = inject<TMagicApp>('app');
const { pageConfig } = useEditorDsl(app);
const { pageConfig } = useEditorDsl();
const pageComponent = useComponent('page');
</script>