feat(core,runtime): 删除App中pages,只留下当前page

This commit is contained in:
roymondchen 2023-03-28 21:06:38 +08:00
parent 0cac40eb31
commit cfd2a6eee3
10 changed files with 100 additions and 79 deletions

View File

@ -18,7 +18,7 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import type { CodeBlockDSL, EventItemConfig, Id, MApp, MPage } from '@tmagic/schema'; import type { CodeBlockDSL, EventItemConfig, Id, MApp } from '@tmagic/schema';
import Env from './Env'; import Env from './Env';
import { bindCommonEventListener, isCommonMethod, triggerCommonMethod } from './events'; import { bindCommonEventListener, isCommonMethod, triggerCommonMethod } from './events';
@ -44,10 +44,10 @@ interface EventCache {
class App extends EventEmitter { class App extends EventEmitter {
public env; public env;
public codeDsl: CodeBlockDSL | undefined; public dsl?: MApp;
public pages = new Map<Id, Page>(); public codeDsl?: CodeBlockDSL;
public page: Page | undefined; public page?: Page;
public platform = 'mobile'; public platform = 'mobile';
public jsEngine = 'browser'; public jsEngine = 'browser';
@ -86,13 +86,15 @@ class App extends EventEmitter {
this.transformStyle = options.transformStyle; this.transformStyle = options.transformStyle;
} }
options.config && this.setConfig(options.config, options.curPage); if (options.config) {
this.setConfig(options.config, options.curPage);
}
bindCommonEventListener(this); bindCommonEventListener(this);
} }
/** /**
* dsl中的style配置转换成cssrem为单位的样式值1001rem * dsl中的style配置转换成cssrem为单位的样式值1001rem
* @param style Object * @param style Object
* @returns Object * @returns Object
*/ */
@ -141,52 +143,60 @@ class App extends EventEmitter {
* @param curPage id * @param curPage id
*/ */
public setConfig(config: MApp, curPage?: Id) { public setConfig(config: MApp, curPage?: Id) {
this.dsl = config;
this.codeDsl = config.codeBlocks; this.codeDsl = config.codeBlocks;
this.pages = new Map();
config.items?.forEach((page) => {
this.addPage(page);
});
this.setPage(curPage || this.page?.data?.id); this.setPage(curPage || this.page?.data?.id);
} }
public addPage(config: MPage) { /**
this.pages.set( *
config.id, * @deprecated
new Page({ */
config, public addPage() {
app: this, console.info('addPage 已经弃用');
}),
);
} }
public setPage(id?: Id) { public setPage(id?: Id) {
let page; const pageConfig = this.dsl?.items.find((page) => page.id === id);
if (id) { if (!pageConfig) {
page = this.pages.get(id); if (this.page) {
this.page.destroy();
this.page = undefined;
}
return;
} }
if (!page) { if (pageConfig === this.page?.data) return;
page = this.pages.get(this.pages.keys().next().value);
if (this.page) {
this.page.destroy();
} }
this.page = page; this.page = new Page({
config: pageConfig,
app: this,
});
if (this.platform !== 'magic') { if (this.platform !== 'magic') {
this.bindEvents(); this.bindEvents();
} }
} }
public deletePage(id: Id) { public deletePage() {
this.pages.delete(id);
if (!this.pages.size) {
this.page = undefined; this.page = undefined;
} }
}
public getPage(id: Id) { /**
return this.pages.get(id); * id参数
* @param id id
* @returns Page | void
*/
public getPage(id?: Id) {
if (!id) return this.page;
if (this.page?.data.id === id) {
return this.page;
}
} }
public registerComponent(type: string, Component: any) { public registerComponent(type: string, Component: any) {
@ -252,7 +262,7 @@ class App extends EventEmitter {
public destroy() { public destroy() {
this.removeAllListeners(); this.removeAllListeners();
this.pages.clear(); this.page = undefined;
} }
private addEventToMap(event: EventCache) { private addEventToMap(event: EventCache) {

View File

@ -70,6 +70,10 @@ class Node extends EventEmitter {
this.emit('updata-data'); this.emit('updata-data');
} }
public destroy() {
this.removeAllListeners();
}
private listenLifeSafe() { private listenLifeSafe() {
this.once('created', async (instance: any) => { this.once('created', async (instance: any) => {
this.instance = instance; this.instance = instance;

View File

@ -61,6 +61,12 @@ class Page extends Node {
public deleteNode(id: Id) { public deleteNode(id: Id) {
this.nodes.delete(id); this.nodes.delete(id);
} }
public destroy(): void {
super.destroy();
this.nodes.clear();
}
} }
export default Page; export default Page;

View File

@ -228,7 +228,7 @@ class Editor extends BaseService {
if (node?.id) { if (node?.id) {
this.get('stage') this.get('stage')
?.renderer.runtime?.getApp?.() ?.renderer.runtime?.getApp?.()
.page?.emit( ?.page?.emit(
'editor:select', 'editor:select',
{ {
node, node,

View File

@ -219,7 +219,7 @@ export interface RemoveData {
} }
export interface Runtime { export interface Runtime {
getApp?: () => Core; getApp?: () => Core | undefined;
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean; beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
updateRootConfig?: (config: MApp) => void; updateRootConfig?: (config: MApp) => void;
updatePageId?: (id: Id) => void; updatePageId?: (id: Id) => void;

View File

@ -39,7 +39,6 @@ const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, designWidth,
config: {},
platform: 'editor', platform: 'editor',
}); });

View File

@ -1,12 +1,12 @@
<template> <template>
<magic-ui-page v-if="pageConfig" :config="pageConfig"></magic-ui-page> <magic-ui-page v-if="pageConfig" :config="pageConfig" :key="pageConfig.id"></magic-ui-page>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, nextTick, provide, reactive, ref, watch } from 'vue'; import { computed, defineComponent, inject, nextTick, reactive, ref, watch } from 'vue';
import Core from '@tmagic/core'; import Core from '@tmagic/core';
import type { Id, MApp, MNode, MPage } from '@tmagic/schema'; import type { Id, MApp, MNode } from '@tmagic/schema';
import { Magic, RemoveData, UpdateData } from '@tmagic/stage'; import { Magic, RemoveData, UpdateData } from '@tmagic/stage';
import { getNodePath } from '@tmagic/utils'; import { getNodePath } from '@tmagic/utils';
@ -19,6 +19,8 @@ declare global {
export default defineComponent({ export default defineComponent({
setup() { setup() {
const app = inject<Core | undefined>('app');
const root = ref<MApp>(); const root = ref<MApp>();
const curPageId = ref<Id>(); const curPageId = ref<Id>();
const selectedId = ref<Id>(); const selectedId = ref<Id>();
@ -27,18 +29,6 @@ export default defineComponent({
() => root.value?.items?.find((item: MNode) => item.id === curPageId.value) || root.value?.items?.[0], () => root.value?.items?.find((item: MNode) => item.id === curPageId.value) || root.value?.items?.[0],
); );
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({
designWidth,
config: root.value,
platform: 'editor',
});
window.appInstance = app;
provide('app', app);
watch(pageConfig, async () => { watch(pageConfig, async () => {
await nextTick(); await nextTick();
const page = document.querySelector<HTMLElement>('.magic-ui-page'); const page = document.querySelector<HTMLElement>('.magic-ui-page');
@ -66,7 +56,7 @@ export default defineComponent({
console.log('select config', id); console.log('select config', id);
selectedId.value = id; selectedId.value = id;
if (app.getPage(id)) { if (app?.getPage(id)) {
this.updatePageId?.(id); this.updatePageId?.(id);
} }
@ -86,9 +76,7 @@ export default defineComponent({
const parent = getNodePath(parentId, [root.value]).pop(); const parent = getNodePath(parentId, [root.value]).pop();
if (!parent) throw new Error('未找到父节点'); if (!parent) throw new Error('未找到父节点');
if (config.type === 'page') { if (config.type !== 'page') {
app?.addPage(config as MPage);
} else {
const parentNode = app?.page?.getNode(parent.id); const parentNode = app?.page?.getNode(parent.id);
parentNode && app?.page?.initNode(config, parentNode); parentNode && app?.page?.initNode(config, parentNode);
} }
@ -114,7 +102,7 @@ export default defineComponent({
const parent = getNodePath(parentId, [root.value]).pop(); const parent = getNodePath(parentId, [root.value]).pop();
if (!parent) throw new Error('未找到父节点'); if (!parent) throw new Error('未找到父节点');
const nodeInstance = app.page?.getNode(config.id); const nodeInstance = app?.page?.getNode(config.id);
if (nodeInstance) { if (nodeInstance) {
nodeInstance.setData(config); nodeInstance.setData(config);
} }
@ -133,9 +121,9 @@ export default defineComponent({
if (!parent) throw new Error('未找到父元素'); if (!parent) throw new Error('未找到父元素');
if (node.type === 'page') { if (node.type === 'page') {
app?.deletePage(node.id); app?.deletePage();
} else { } else {
app.page?.deleteNode(node.id); app?.page?.deleteNode(node.id);
} }
const index = parent.items?.findIndex((child: MNode) => child.id === node.id); const index = parent.items?.findIndex((child: MNode) => child.id === node.id);

View File

@ -18,6 +18,8 @@
import Vue from 'vue'; import Vue from 'vue';
import Core from '@tmagic/core';
import App from './App.vue'; import App from './App.vue';
Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]).then(([components, plugins]) => { Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]).then(([components, plugins]) => {
@ -29,9 +31,21 @@ Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]
Vue.use(plugin); Vue.use(plugin);
}); });
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({
designWidth,
platform: 'editor',
});
Vue.prototype.app = app;
new Vue({ new Vue({
// @ts-ignore // @ts-ignore
render: (h) => h(App), render: (h) => h(App),
provide: {
app,
},
el: '#app', el: '#app',
}); });
}); });

View File

@ -1,12 +1,12 @@
<template> <template>
<magic-ui-page v-if="pageConfig" :config="pageConfig"></magic-ui-page> <magic-ui-page v-if="pageConfig" :key="pageConfig.id" :config="pageConfig"></magic-ui-page>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, nextTick, provide, reactive, ref, watch } from 'vue'; import { computed, defineComponent, inject, nextTick, reactive, ref, watch } from 'vue';
import Core from '@tmagic/core'; import Core from '@tmagic/core';
import type { Id, MApp, MNode, MPage } from '@tmagic/schema'; import type { Id, MApp, MNode } from '@tmagic/schema';
import { Magic, RemoveData, UpdateData } from '@tmagic/stage'; import { Magic, RemoveData, UpdateData } from '@tmagic/stage';
import { getNodePath } from '@tmagic/utils'; import { getNodePath } from '@tmagic/utils';
@ -18,6 +18,8 @@ declare global {
export default defineComponent({ export default defineComponent({
setup() { setup() {
const app = inject<Core | undefined>('app');
const root = ref<MApp>(); const root = ref<MApp>();
const curPageId = ref<Id>(); const curPageId = ref<Id>();
const selectedId = ref<Id>(); const selectedId = ref<Id>();
@ -26,17 +28,6 @@ export default defineComponent({
() => root.value?.items?.find((item: MNode) => item.id === curPageId.value) || root.value?.items?.[0], () => root.value?.items?.find((item: MNode) => item.id === curPageId.value) || root.value?.items?.[0],
); );
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({
designWidth,
config: root.value,
platform: 'editor',
});
window.appInstance = app;
provide('app', app);
watch(pageConfig, async () => { watch(pageConfig, async () => {
await nextTick(); await nextTick();
const page = document.querySelector<HTMLElement>('.magic-ui-page'); const page = document.querySelector<HTMLElement>('.magic-ui-page');
@ -64,7 +55,7 @@ export default defineComponent({
console.log('select config', id); console.log('select config', id);
selectedId.value = id; selectedId.value = id;
if (app.getPage(id)) { if (app?.getPage(id)) {
this.updatePageId?.(id); this.updatePageId?.(id);
} }
@ -84,9 +75,7 @@ export default defineComponent({
const parent = getNodePath(parentId, [root.value]).pop(); const parent = getNodePath(parentId, [root.value]).pop();
if (!parent) throw new Error('未找到父节点'); if (!parent) throw new Error('未找到父节点');
if (config.type === 'page') { if (config.type !== 'page') {
app?.addPage(config as MPage);
} else {
const parentNode = app?.page?.getNode(parent.id); const parentNode = app?.page?.getNode(parent.id);
parentNode && app?.page?.initNode(config, parentNode); parentNode && app?.page?.initNode(config, parentNode);
} }
@ -112,7 +101,7 @@ export default defineComponent({
if (!node) throw new Error('未找到目标节点'); if (!node) throw new Error('未找到目标节点');
if (!parent) throw new Error('未找到父节点'); if (!parent) throw new Error('未找到父节点');
const nodeInstance = app.page?.getNode(config.id); const nodeInstance = app?.page?.getNode(config.id);
if (nodeInstance) { if (nodeInstance) {
nodeInstance.setData(config); nodeInstance.setData(config);
} }
@ -131,9 +120,9 @@ export default defineComponent({
if (!parent) throw new Error('未找到父元素'); if (!parent) throw new Error('未找到父元素');
if (node.type === 'page') { if (node.type === 'page') {
app?.deletePage(node.id); app?.deletePage();
} else { } else {
app.page?.deleteNode(node.id); app?.page?.deleteNode(node.id);
} }
const index = parent.items?.findIndex((child: MNode) => child.id === node.id); const index = parent.items?.findIndex((child: MNode) => child.id === node.id);

View File

@ -18,6 +18,8 @@
import { createApp } from 'vue'; import { createApp } from 'vue';
import Core from '@tmagic/core';
import App from './App.vue'; import App from './App.vue';
Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]).then(([components, plugins]) => { Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]).then(([components, plugins]) => {
@ -31,5 +33,14 @@ Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]
magicApp.use(plugin); magicApp.use(plugin);
}); });
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({
designWidth,
platform: 'editor',
});
magicApp.config.globalProperties.app = app;
magicApp.provide('app', app);
magicApp.mount('#app'); magicApp.mount('#app');
}); });