diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index da2ec9b4..6cbd6b38 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -20,7 +20,8 @@ import { EventEmitter } from 'events'; import { isEmpty } from 'lodash-es'; -import { DeprecatedEventConfig, EventConfig, HookType, MComponent, MContainer, MPage } from '@tmagic/schema'; +import type { DeprecatedEventConfig, EventConfig, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema'; +import { HookType } from '@tmagic/schema'; import type App from './App'; import type Page from './Page'; @@ -33,7 +34,7 @@ interface NodeOptions { app: App; } class Node extends EventEmitter { - public data: MComponent | MContainer | MPage; + public data: MComponent | MContainer | MPage | MPageFragment; public style?: { [key: string]: any; }; @@ -56,9 +57,9 @@ class Node extends EventEmitter { this.listenLifeSafe(); } - public setData(data: MComponent | MContainer | MPage) { + public setData(data: MComponent | MContainer | MPage | MPageFragment) { this.data = data; - this.emit('updata-data'); + this.emit('update-data'); } public destroy() { diff --git a/packages/core/src/Page.ts b/packages/core/src/Page.ts index 51def7aa..9dc1f7fa 100644 --- a/packages/core/src/Page.ts +++ b/packages/core/src/Page.ts @@ -16,12 +16,12 @@ * limitations under the License. */ -import type { Id, MComponent, MContainer, MPage } from '@tmagic/schema'; +import type { Id, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema'; import type App from './App'; import Node from './Node'; interface ConfigOptions { - config: MPage; + config: MPage | MPageFragment; app: App; } @@ -45,6 +45,13 @@ class Page extends Node { this.setNode(config.id, node); + if (config.type === 'page-fragment-container' && config.pageFragmentId) { + const pageFragment = this.app.dsl?.items?.find((page) => page.id === config.pageFragmentId); + if (pageFragment) { + config.items = [pageFragment]; + } + } + config.items?.forEach((element: MComponent | MContainer) => { this.initNode(element, node); }); diff --git a/packages/editor/src/Editor.vue b/packages/editor/src/Editor.vue index 76672144..ba1f5620 100644 --- a/packages/editor/src/Editor.vue +++ b/packages/editor/src/Editor.vue @@ -1,5 +1,5 @@ @@ -89,6 +87,9 @@ + + + diff --git a/packages/editor/src/editorProps.ts b/packages/editor/src/editorProps.ts index 076b3406..bd6cd550 100644 --- a/packages/editor/src/editorProps.ts +++ b/packages/editor/src/editorProps.ts @@ -72,8 +72,12 @@ export interface EditorProps { extendFormState?: (state: FormState) => Record | Promise>; /** 自定义依赖收集器,复制组件时会将关联依赖一并复制 */ collectorOptions?: CustomTargetOptions; + /** 标尺配置 */ guidesOptions?: Partial; + /** 禁止多选 */ disabledMultiSelect?: boolean; + /** 禁用页面片 */ + disabledPageFragment?: boolean; customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[]; } @@ -96,4 +100,5 @@ export const defaultEditorProps = { codeOptions: () => ({}), renderType: RenderType.IFRAME, disabledMultiSelect: false, + disabledPageFragment: false, }; diff --git a/packages/editor/src/fields/PageFragmentSelect.vue b/packages/editor/src/fields/PageFragmentSelect.vue new file mode 100644 index 00000000..dc20f195 --- /dev/null +++ b/packages/editor/src/fields/PageFragmentSelect.vue @@ -0,0 +1,55 @@ + + + diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index e8b81f7b..b36c4468 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -30,6 +30,7 @@ import DataSourceMocks from './fields/DataSourceMocks.vue'; import DataSourceSelect from './fields/DataSourceSelect.vue'; import EventSelect from './fields/EventSelect.vue'; import KeyValue from './fields/KeyValue.vue'; +import PageFragmentSelect from './fields/PageFragmentSelect.vue'; import uiSelect from './fields/UISelect.vue'; import CodeEditor from './layouts/CodeEditor.vue'; import { setConfig } from './utils/config'; @@ -79,6 +80,7 @@ export { default as LayoutContainer } from './components/SplitView.vue'; export { default as SplitView } from './components/SplitView.vue'; export { default as Resizer } from './components/Resizer.vue'; export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue'; +export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue'; const defaultInstallOpt: InstallOptions = { // eslint-disable-next-line no-eval @@ -108,5 +110,6 @@ export default { app.component('m-fields-data-source-methods', DataSourceMethods); app.component('m-fields-data-source-method-select', DataSourceMethodSelect); app.component('m-fields-data-source-field-select', DataSourceFieldSelect); + app.component('m-fields-page-fragment-select', PageFragmentSelect); }, }; diff --git a/packages/editor/src/initService.ts b/packages/editor/src/initService.ts index 4463649a..9f6734c2 100644 --- a/packages/editor/src/initService.ts +++ b/packages/editor/src/initService.ts @@ -11,7 +11,7 @@ import { DepTargetType, Target, } from '@tmagic/dep'; -import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema'; +import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { getNodes } from '@tmagic/utils'; import PropsPanel from './layouts/PropsPanel.vue'; @@ -350,7 +350,7 @@ export const initServiceEvents = ( }; // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖 - const historyChangeHandler = (page: MPage) => { + const historyChangeHandler = (page: MPage | MPageFragment) => { depService.collect([page], true); }; diff --git a/packages/editor/src/layouts/AddPageBox.vue b/packages/editor/src/layouts/AddPageBox.vue index 99f42ad7..d82f4265 100644 --- a/packages/editor/src/layouts/AddPageBox.vue +++ b/packages/editor/src/layouts/AddPageBox.vue @@ -1,12 +1,19 @@ @@ -25,9 +32,13 @@ defineOptions({ name: 'MEditorAddPageBox', }); +defineProps<{ + disabledPageFragment: boolean; +}>(); + const services = inject('services'); -const clickHandler = () => { +const clickHandler = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => { const { editorService } = services || {}; if (!editorService) return; @@ -36,8 +47,9 @@ const clickHandler = () => { if (!root) throw new Error('root 不能为空'); editorService.add({ - type: NodeType.PAGE, - name: generatePageNameByApp(root), + type, + name: generatePageNameByApp(root, type), + items: [], }); }; diff --git a/packages/editor/src/layouts/Framework.vue b/packages/editor/src/layouts/Framework.vue index bb6fce94..0df652dd 100644 --- a/packages/editor/src/layouts/Framework.vue +++ b/packages/editor/src/layouts/Framework.vue @@ -31,13 +31,18 @@ -