@tmagic/editor 1.1.0-beta.8 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/style.css +46 -0
  2. package/dist/tmagic-editor.mjs +1052 -873
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +1054 -872
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +31 -9
  8. package/src/components/ContentMenu.vue +4 -4
  9. package/src/components/Icon.vue +6 -20
  10. package/src/components/ScrollBar.vue +147 -0
  11. package/src/components/ScrollViewer.vue +89 -44
  12. package/src/components/ToolButton.vue +40 -138
  13. package/src/fields/UISelect.vue +2 -2
  14. package/src/index.ts +2 -0
  15. package/src/layouts/NavMenu.vue +156 -23
  16. package/src/layouts/PropsPanel.vue +49 -51
  17. package/src/layouts/sidebar/LayerMenu.vue +3 -3
  18. package/src/layouts/sidebar/LayerPanel.vue +39 -8
  19. package/src/layouts/workspace/PageBar.vue +1 -1
  20. package/src/layouts/workspace/Stage.vue +8 -86
  21. package/src/layouts/workspace/ViewerMenu.vue +6 -6
  22. package/src/layouts/workspace/Workspace.vue +133 -138
  23. package/src/services/componentList.ts +5 -0
  24. package/src/services/editor.ts +148 -76
  25. package/src/services/events.ts +8 -2
  26. package/src/services/props.ts +31 -52
  27. package/src/services/storage.ts +4 -0
  28. package/src/services/ui.ts +32 -30
  29. package/src/theme/nav-menu.scss +6 -0
  30. package/src/type.ts +28 -11
  31. package/src/utils/index.ts +1 -0
  32. package/src/utils/operator.ts +6 -60
  33. package/src/utils/props.ts +0 -3
  34. package/src/utils/scroll-viewer.ts +90 -158
  35. package/src/utils/stage.ts +91 -0
  36. package/types/Editor.vue.d.ts +17 -8
  37. package/types/components/ContentMenu.vue.d.ts +8 -8
  38. package/types/components/Icon.vue.d.ts +62 -12
  39. package/types/components/ScrollBar.vue.d.ts +83 -0
  40. package/types/components/ScrollViewer.vue.d.ts +131 -19
  41. package/types/components/ToolButton.vue.d.ts +56 -59
  42. package/types/index.d.ts +2 -0
  43. package/types/layouts/NavMenu.vue.d.ts +92 -23
  44. package/types/layouts/PropsPanel.vue.d.ts +25 -208
  45. package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
  46. package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
  47. package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
  48. package/types/services/componentList.d.ts +1 -0
  49. package/types/services/editor.d.ts +7 -9
  50. package/types/services/events.d.ts +1 -0
  51. package/types/services/props.d.ts +41 -9
  52. package/types/services/storage.d.ts +1 -0
  53. package/types/services/ui.d.ts +3 -1
  54. package/types/type.d.ts +25 -11
  55. package/types/utils/index.d.ts +1 -0
  56. package/types/utils/operator.d.ts +1 -7
  57. package/types/utils/props.d.ts +0 -1
  58. package/types/utils/scroll-viewer.d.ts +16 -18
  59. package/types/utils/stage.d.ts +3 -0
@@ -2,169 +2,80 @@
2
2
  <div
3
3
  v-if="display"
4
4
  class="menu-item"
5
- :class="item.type"
6
- @click="clickHandler(item, $event)"
7
- @mousedown="mousedownHandler(item, $event)"
8
- @mouseup="mouseupHandler(item, $event)"
5
+ :class="`${data.type} ${data.className || ''}`"
6
+ @click="clickHandler(data, $event)"
7
+ @mousedown="mousedownHandler(data, $event)"
8
+ @mouseup="mouseupHandler(data, $event)"
9
9
  >
10
- <el-divider v-if="item.type === 'divider'" :direction="item.direction || 'vertical'"></el-divider>
11
- <div v-else-if="item.type === 'text'" class="menu-item-text">{{ item.text }}</div>
10
+ <el-divider v-if="data.type === 'divider'" :direction="data.direction || 'vertical'"></el-divider>
11
+ <div v-else-if="data.type === 'text'" class="menu-item-text">{{ data.text }}</div>
12
12
 
13
- <template v-else-if="item.type === 'zoom'">
14
- <tool-button
15
- :data="{ type: 'button', icon: ZoomOut, handler: zoomOutHandler, tooltip: '缩小' }"
16
- :event-type="eventType"
17
- ></tool-button>
18
- <span class="menu-item-text" style="margin: 0 5px">{{ parseInt(`${zoom * 100}`, 10) }}%</span>
19
- <tool-button
20
- :data="{ type: 'button', icon: ZoomIn, handler: zoomInHandler, tooltip: '放大' }"
21
- :event-type="eventType"
22
- ></tool-button>
23
- </template>
24
-
25
- <template v-else-if="item.type === 'button'">
26
- <el-tooltip v-if="item.tooltip" effect="dark" placement="bottom-start" :content="item.tooltip">
13
+ <template v-else-if="data.type === 'button'">
14
+ <el-tooltip v-if="data.tooltip" effect="dark" placement="bottom-start" :content="data.tooltip">
27
15
  <el-button size="small" text :disabled="disabled"
28
- ><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
16
+ ><MIcon v-if="data.icon" :icon="data.icon"></MIcon><span>{{ data.text }}</span></el-button
29
17
  >
30
18
  </el-tooltip>
31
19
  <el-button v-else size="small" text :disabled="disabled"
32
- ><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
20
+ ><MIcon v-if="data.icon" :icon="data.icon"></MIcon><span>{{ data.text }}</span></el-button
33
21
  >
34
22
  </template>
35
23
 
36
- <el-dropdown v-else-if="item.type === 'dropdown'" trigger="click" :disabled="disabled" @command="dropdownHandler">
24
+ <el-dropdown v-else-if="data.type === 'dropdown'" trigger="click" :disabled="disabled" @command="dropdownHandler">
37
25
  <span class="el-dropdown-link menubar-menu-button">
38
- {{ item.text }}<el-icon class="el-icon--right"><arrow-down></arrow-down></el-icon>
26
+ {{ data.text }}<el-icon class="el-icon--right"><ArrowDown></ArrowDown></el-icon>
39
27
  </span>
40
28
  <template #dropdown>
41
- <el-dropdown-menu v-if="item.items && item.items.length">
42
- <el-dropdown-item v-for="(subItem, index) in item.items" :key="index" :command="{ item, subItem }">{{
29
+ <el-dropdown-menu v-if="data.items && data.items.length">
30
+ <el-dropdown-item v-for="(subItem, index) in data.items" :key="index" :command="{ data, subItem }">{{
43
31
  subItem.text
44
32
  }}</el-dropdown-item>
45
33
  </el-dropdown-menu>
46
34
  </template>
47
35
  </el-dropdown>
48
36
 
49
- <component v-else-if="item.type === 'component'" v-bind="item.props || {}" :is="item.component"></component>
37
+ <component v-else-if="data.type === 'component'" v-bind="data.props || {}" :is="data.component"></component>
50
38
  </div>
51
39
  </template>
52
40
 
53
41
  <script lang="ts" setup>
54
- import { computed, inject, markRaw, PropType } from 'vue';
55
- import { ArrowDown, Back, Delete, Grid, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons-vue';
56
-
57
- import { NodeType } from '@tmagic/schema';
42
+ import { computed, inject } from 'vue';
43
+ import { ArrowDown } from '@element-plus/icons-vue';
58
44
 
59
45
  import MIcon from '../components/Icon.vue';
60
- import type { MenuButton, MenuComponent, MenuItem, Services } from '../type';
61
-
62
- const props = defineProps({
63
- data: {
64
- type: [Object, String] as PropType<MenuItem | string>,
65
- require: true,
66
- default: () => ({
46
+ import type { MenuButton, MenuComponent, Services } from '../type';
47
+
48
+ const props = withDefaults(
49
+ defineProps<{
50
+ data?: MenuButton | MenuComponent;
51
+ eventType?: 'mousedown' | 'mouseup' | 'click';
52
+ }>(),
53
+ {
54
+ data: () => ({
67
55
  type: 'text',
68
56
  display: false,
69
57
  }),
58
+ eventType: 'click',
70
59
  },
71
-
72
- eventType: {
73
- type: String as PropType<'mousedown' | 'mouseup' | 'click'>,
74
- default: 'click',
75
- },
76
- });
77
-
60
+ );
78
61
  const services = inject<Services>('services');
79
- const uiService = services?.uiService;
80
-
81
- const zoom = computed((): number => uiService?.get<number>('zoom') ?? 1);
82
- const showGuides = computed((): boolean => uiService?.get<boolean>('showGuides') ?? true);
83
- const showRule = computed((): boolean => uiService?.get<boolean>('showRule') ?? true);
84
62
 
85
- const zoomInHandler = () => uiService?.zoom(0.1);
86
- const zoomOutHandler = () => uiService?.zoom(-0.1);
87
-
88
- const item = computed((): MenuButton | MenuComponent => {
89
- if (typeof props.data !== 'string') {
90
- return props.data;
91
- }
92
- switch (props.data) {
93
- case '/':
94
- return {
95
- type: 'divider',
96
- };
97
- case 'zoom':
98
- return {
99
- type: 'zoom',
100
- };
101
- case 'delete':
102
- return {
103
- type: 'button',
104
- icon: markRaw(Delete),
105
- tooltip: '刪除',
106
- disabled: () => services?.editorService.get('node')?.type === NodeType.PAGE,
107
- handler: () => services?.editorService.remove(services?.editorService.get('node')),
108
- };
109
- case 'undo':
110
- return {
111
- type: 'button',
112
- icon: markRaw(Back),
113
- tooltip: '后退',
114
- disabled: () => !services?.historyService.state.canUndo,
115
- handler: () => services?.editorService.undo(),
116
- };
117
- case 'redo':
118
- return {
119
- type: 'button',
120
- icon: markRaw(Right),
121
- tooltip: '前进',
122
- disabled: () => !services?.historyService.state.canRedo,
123
- handler: () => services?.editorService.redo(),
124
- };
125
- case 'zoom-in':
126
- return {
127
- type: 'button',
128
- icon: markRaw(ZoomIn),
129
- tooltip: '放大',
130
- handler: zoomInHandler,
131
- };
132
- case 'zoom-out':
133
- return {
134
- type: 'button',
135
- icon: markRaw(ZoomOut),
136
- tooltip: '縮小',
137
- handler: zoomOutHandler,
138
- };
139
- case 'rule':
140
- return {
141
- type: 'button',
142
- icon: markRaw(ScaleToOriginal),
143
- tooltip: showRule.value ? '隐藏标尺' : '显示标尺',
144
- handler: () => uiService?.set('showRule', !showRule.value),
145
- };
146
- case 'guides':
147
- return {
148
- type: 'button',
149
- icon: markRaw(Grid),
150
- tooltip: showGuides.value ? '隐藏参考线' : '显示参考线',
151
- handler: () => uiService?.set('showGuides', !showGuides.value),
152
- };
153
- default:
154
- return {
155
- type: 'text',
156
- text: props.data,
157
- };
63
+ const disabled = computed(() => {
64
+ if (typeof props.data === 'string') return false;
65
+ if (props.data.type === 'component') return false;
66
+ if (typeof props.data.disabled === 'function') {
67
+ return props.data.disabled(services);
158
68
  }
69
+ return props.data.disabled;
159
70
  });
160
71
 
161
- const disabled = computed(() => {
162
- if (typeof item.value === 'string') return false;
163
- if (item.value.type === 'component') return false;
164
- if (typeof item.value.disabled === 'function') {
165
- return item.value.disabled(services);
72
+ const display = computed(() => {
73
+ if (!props.data) return false;
74
+ if (typeof props.data === 'string') return true;
75
+ if (typeof props.data.display === 'function') {
76
+ return props.data.display(services);
166
77
  }
167
- return item.value.disabled;
78
+ return props.data.display ?? true;
168
79
  });
169
80
 
170
81
  const buttonHandler = (item: MenuButton | MenuComponent, event: MouseEvent) => {
@@ -174,15 +85,6 @@ const buttonHandler = (item: MenuButton | MenuComponent, event: MouseEvent) => {
174
85
  }
175
86
  };
176
87
 
177
- const display = computed(() => {
178
- if (!item.value) return false;
179
- if (typeof item.value === 'string') return true;
180
- if (typeof item.value.display === 'function') {
181
- return item.value.display(services);
182
- }
183
- return item.value.display ?? true;
184
- });
185
-
186
88
  const dropdownHandler = (command: any) => {
187
89
  if (command.item.handler) {
188
90
  command.item.handler(services);
@@ -3,8 +3,8 @@
3
3
  <el-button type="danger" :icon="Delete" text style="padding: 0">取消</el-button>
4
4
  </div>
5
5
  <div class="m-fields-ui-select" v-else @click="startSelect" style="display: flex">
6
- <el-tooltip content="清除">
7
- <el-button v-if="val" style="padding: 0" type="danger" :icon="Close" text @click.stop="deleteHandler"></el-button>
6
+ <el-tooltip v-if="val" content="清除">
7
+ <el-button style="padding: 0" type="danger" :icon="Close" text @click.stop="deleteHandler"></el-button>
8
8
  </el-tooltip>
9
9
  <el-tooltip :content="val ? toName + '_' + val : '点击此处选择'">
10
10
  <el-button text style="padding: 0; margin: 0">{{ val ? toName + '_' + val : '点击此处选择' }}</el-button>
package/src/index.ts CHANGED
@@ -44,6 +44,8 @@ export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPa
44
44
  export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
45
45
  export { default as PropsPanel } from './layouts/PropsPanel.vue';
46
46
  export { default as ToolButton } from './components/ToolButton.vue';
47
+ export { default as ContentMenu } from './components/ContentMenu.vue';
48
+ export { default as Icon } from './components/Icon.vue';
47
49
 
48
50
  const defaultInstallOpt: InstallOptions = {
49
51
  // @todo, 自定义图片上传方法等编辑器依赖的外部选项
@@ -1,41 +1,174 @@
1
1
  <template>
2
2
  <div class="m-editor-nav-menu" :style="{ height: `${height}px` }">
3
3
  <div v-for="key in keys" :class="`menu-${key}`" :key="key" :style="`width: ${columnWidth?.[key]}px`">
4
- <tool-button :data="item" v-for="(item, index) in data[key]" :key="index"></tool-button>
4
+ <tool-button :data="item" v-for="(item, index) in buttons[key]" :key="index"></tool-button>
5
5
  </div>
6
6
  </div>
7
7
  </template>
8
8
 
9
- <script lang="ts">
10
- import { computed, defineComponent, inject, PropType } from 'vue';
9
+ <script lang="ts" setup>
10
+ import { computed, inject, markRaw } from 'vue';
11
+ import { Back, Delete, FullScreen, Grid, Memo, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons-vue';
12
+
13
+ import { NodeType } from '@tmagic/schema';
11
14
 
12
15
  import ToolButton from '../components/ToolButton.vue';
13
- import { GetColumnWidth, MenuBarData, Services } from '../type';
16
+ import { ColumnLayout, GetColumnWidth, MenuBarData, MenuButton, MenuComponent, MenuItem, Services } from '../type';
14
17
 
15
- export default defineComponent({
16
- name: 'nav-menu',
18
+ const props = withDefaults(
19
+ defineProps<{
20
+ data?: MenuBarData;
21
+ height?: number;
22
+ }>(),
23
+ {
24
+ data: () => ({}),
25
+ height: 35,
26
+ },
27
+ );
17
28
 
18
- components: { ToolButton },
29
+ const services = inject<Services>('services');
30
+ const uiService = services?.uiService;
19
31
 
20
- props: {
21
- data: {
22
- type: Object as PropType<MenuBarData>,
23
- default: () => ({}),
24
- },
32
+ const columnWidth = computed(() => services?.uiService.get<GetColumnWidth>('columnWidth'));
33
+ const keys = Object.values(ColumnLayout);
25
34
 
26
- height: {
27
- type: Number,
28
- },
29
- },
35
+ const showGuides = computed((): boolean => uiService?.get<boolean>('showGuides') ?? true);
36
+ const showRule = computed((): boolean => uiService?.get<boolean>('showRule') ?? true);
37
+ const zoom = computed((): number => uiService?.get<number>('zoom') ?? 1);
30
38
 
31
- setup(props) {
32
- const services = inject<Services>('services');
39
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
40
+ const ctrl = isMac ? 'Command' : 'Ctrl';
33
41
 
34
- return {
35
- keys: computed(() => Object.keys(props.data) as Array<keyof MenuBarData>),
42
+ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
43
+ if (typeof item !== 'string') {
44
+ return [item];
45
+ }
46
+ const config: (MenuButton | MenuComponent)[] = [];
47
+ switch (item) {
48
+ case '/':
49
+ config.push({
50
+ type: 'divider',
51
+ className: 'divider',
52
+ });
53
+ break;
54
+ case 'zoom':
55
+ config.push(
56
+ ...getConfig('zoom-out'),
57
+ ...getConfig(`${parseInt(`${zoom.value * 100}`, 10)}%`),
58
+ ...getConfig('zoom-in'),
59
+ ...getConfig('scale-to-original'),
60
+ ...getConfig('scale-to-fit'),
61
+ );
62
+ break;
63
+ case 'delete':
64
+ config.push({
65
+ type: 'button',
66
+ className: 'delete',
67
+ icon: markRaw(Delete),
68
+ tooltip: `刪除(Delete)`,
69
+ disabled: () => services?.editorService.get('node')?.type === NodeType.PAGE,
70
+ handler: () => services?.editorService.remove(services?.editorService.get('node')),
71
+ });
72
+ break;
73
+ case 'undo':
74
+ config.push({
75
+ type: 'button',
76
+ className: 'undo',
77
+ icon: markRaw(Back),
78
+ tooltip: `后退(${ctrl}+z)`,
79
+ disabled: () => !services?.historyService.state.canUndo,
80
+ handler: () => services?.editorService.undo(),
81
+ });
82
+ break;
83
+ case 'redo':
84
+ config.push({
85
+ type: 'button',
86
+ className: 'redo',
87
+ icon: markRaw(Right),
88
+ tooltip: `前进(${ctrl}+Shift+z)`,
89
+ disabled: () => !services?.historyService.state.canRedo,
90
+ handler: () => services?.editorService.redo(),
91
+ });
92
+ break;
93
+ case 'zoom-in':
94
+ config.push({
95
+ type: 'button',
96
+ className: 'zoom-in',
97
+ icon: markRaw(ZoomIn),
98
+ tooltip: `放大(${ctrl}+=)`,
99
+ handler: () => uiService?.zoom(0.1),
100
+ });
101
+ break;
102
+ case 'zoom-out':
103
+ config.push({
104
+ type: 'button',
105
+ className: 'zoom-out',
106
+ icon: markRaw(ZoomOut),
107
+ tooltip: `縮小(${ctrl}+-)`,
108
+ handler: () => uiService?.zoom(-0.1),
109
+ });
110
+ break;
111
+ case 'scale-to-original':
112
+ config.push({
113
+ type: 'button',
114
+ className: 'scale-to-original',
115
+ icon: markRaw(ScaleToOriginal),
116
+ tooltip: `缩放到实际大小(${ctrl}+1)`,
117
+ handler: () => uiService?.set('zoom', 1),
118
+ });
119
+ break;
120
+ case 'scale-to-fit':
121
+ config.push({
122
+ type: 'button',
123
+ className: 'scale-to-fit',
124
+ icon: markRaw(FullScreen),
125
+ tooltip: `缩放以适应(${ctrl}+0)`,
126
+ handler: () => uiService?.set('zoom', uiService.calcZoom()),
127
+ });
128
+ break;
129
+ case 'rule':
130
+ config.push({
131
+ type: 'button',
132
+ className: 'rule',
133
+ icon: markRaw(Memo),
134
+ tooltip: showRule.value ? '隐藏标尺' : '显示标尺',
135
+ handler: () => uiService?.set('showRule', !showRule.value),
136
+ });
137
+ break;
138
+ case 'guides':
139
+ config.push({
140
+ type: 'button',
141
+ className: 'guides',
142
+ icon: markRaw(Grid),
143
+ tooltip: showGuides.value ? '隐藏参考线' : '显示参考线',
144
+ handler: () => uiService?.set('showGuides', !showGuides.value),
145
+ });
146
+ break;
147
+ default:
148
+ config.push({
149
+ type: 'text',
150
+ text: item,
151
+ });
152
+ }
153
+ return config;
154
+ };
36
155
 
37
- columnWidth: computed(() => services?.uiService.get<GetColumnWidth>('columnWidth')),
38
- };
39
- },
156
+ const buttons = computed(() => {
157
+ const data: {
158
+ [ColumnLayout.LEFT]: (MenuButton | MenuComponent)[];
159
+ [ColumnLayout.CENTER]: (MenuButton | MenuComponent)[];
160
+ [ColumnLayout.RIGHT]: (MenuButton | MenuComponent)[];
161
+ } = {
162
+ [ColumnLayout.LEFT]: [],
163
+ [ColumnLayout.CENTER]: [],
164
+ [ColumnLayout.RIGHT]: [],
165
+ };
166
+ keys.forEach((key) => {
167
+ const items = props.data[key] || [];
168
+ items.forEach((item) => {
169
+ data[key].push(...getConfig(item));
170
+ });
171
+ });
172
+ return data;
40
173
  });
41
174
  </script>
@@ -2,9 +2,9 @@
2
2
  <div class="`m-editor-props-panel">
3
3
  <slot name="props-panel-header"></slot>
4
4
  <m-form
5
+ ref="configForm"
5
6
  :class="`m-editor-props-panel ${propsPanelSize}`"
6
7
  :popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
7
- ref="configForm"
8
8
  :size="propsPanelSize"
9
9
  :init-values="values"
10
10
  :config="curFormConfig"
@@ -13,69 +13,67 @@
13
13
  </div>
14
14
  </template>
15
15
 
16
- <script lang="ts">
17
- import { computed, defineComponent, getCurrentInstance, inject, onMounted, ref, watchEffect } from 'vue';
16
+ <script lang="ts" setup>
17
+ import { computed, getCurrentInstance, inject, onMounted, ref, watchEffect } from 'vue';
18
18
  import { ElMessage } from 'element-plus';
19
19
 
20
20
  import type { FormValue, MForm } from '@tmagic/form';
21
21
  import type { MNode } from '@tmagic/schema';
22
+ import type StageCore from '@tmagic/stage';
22
23
 
23
24
  import type { Services } from '../type';
24
25
 
25
- export default defineComponent({
26
- name: 'm-editor-props-panel',
26
+ const emit = defineEmits(['mounted']);
27
27
 
28
- emits: ['mounted'],
28
+ const internalInstance = getCurrentInstance();
29
+ const values = ref<FormValue>({});
30
+ const configForm = ref<InstanceType<typeof MForm>>();
31
+ // ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
32
+ const curFormConfig = ref<any>([]);
33
+ const services = inject<Services>('services');
34
+ const node = computed(() => services?.editorService.get<MNode | null>('node'));
35
+ const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
36
+ const stage = computed(() => services?.editorService.get<StageCore>('stage'));
29
37
 
30
- setup(props, { emit }) {
31
- const internalInstance = getCurrentInstance();
32
- const values = ref<FormValue>({});
33
- const configForm = ref<InstanceType<typeof MForm>>();
34
- // ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
35
- const curFormConfig = ref<any>([]);
36
- const services = inject<Services>('services');
37
- const node = computed(() => services?.editorService.get<MNode | null>('node'));
38
+ const init = async () => {
39
+ if (!node.value) {
40
+ curFormConfig.value = [];
41
+ return;
42
+ }
38
43
 
39
- const init = async () => {
40
- if (!node.value) {
41
- curFormConfig.value = [];
42
- return;
43
- }
44
+ const type = node.value.type || (node.value.items ? 'container' : 'text');
45
+ curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
46
+ values.value = node.value;
47
+ };
44
48
 
45
- const type = node.value.type || (node.value.items ? 'container' : 'text');
46
- curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
47
- values.value = node.value;
48
- };
49
+ watchEffect(init);
50
+ services?.propsService.on('props-configs-change', init);
49
51
 
50
- watchEffect(init);
51
- services?.propsService.on('props-configs-change', init);
52
+ onMounted(() => {
53
+ emit('mounted', internalInstance);
54
+ });
52
55
 
53
- onMounted(() => {
54
- emit('mounted', internalInstance);
55
- });
56
+ watchEffect(() => {
57
+ if (configForm.value && stage.value) {
58
+ configForm.value.formState.stage = stage.value;
59
+ }
60
+ });
56
61
 
57
- return {
58
- values,
59
- configForm,
60
- curFormConfig,
61
- propsPanelSize: computed(() => services?.uiService.get('propsPanelSize') || 'small'),
62
+ const submit = async () => {
63
+ try {
64
+ const values = await configForm.value?.submitForm();
65
+ services?.editorService.update(values);
66
+ } catch (e: any) {
67
+ console.error(e);
68
+ ElMessage.closeAll();
69
+ ElMessage.error({
70
+ duration: 10000,
71
+ showClose: true,
72
+ message: e.message,
73
+ dangerouslyUseHTMLString: true,
74
+ });
75
+ }
76
+ };
62
77
 
63
- async submit() {
64
- try {
65
- const values = await configForm.value?.submitForm();
66
- services?.editorService.update(values);
67
- } catch (e: any) {
68
- console.error(e);
69
- ElMessage.closeAll();
70
- ElMessage.error({
71
- duration: 10000,
72
- showClose: true,
73
- message: e.message,
74
- dangerouslyUseHTMLString: true,
75
- });
76
- }
77
- },
78
- };
79
- },
80
- });
78
+ defineExpose({ submit });
81
79
  </script>
@@ -9,7 +9,7 @@ import { Delete, DocumentCopy, Files, Plus } from '@element-plus/icons-vue';
9
9
  import { NodeType } from '@tmagic/schema';
10
10
 
11
11
  import ContentMenu from '../../components/ContentMenu.vue';
12
- import type { ComponentGroup, MenuButton, MenuItem, Services } from '../../type';
12
+ import type { ComponentGroup, MenuButton, MenuComponent, Services } from '../../type';
13
13
 
14
14
  export default defineComponent({
15
15
  components: { ContentMenu },
@@ -22,7 +22,7 @@ export default defineComponent({
22
22
  const isPage = computed(() => node.value?.type === NodeType.PAGE);
23
23
  const componentList = computed(() => services?.componentListService.getList() || []);
24
24
 
25
- const layerContentMenu = inject<MenuItem[]>('layerContentMenu', []);
25
+ const layerContentMenu = inject<(MenuComponent | MenuButton)[]>('layerContentMenu', []);
26
26
 
27
27
  const createMenuItems = (group: ComponentGroup): MenuButton[] =>
28
28
  group.items.map((component) => ({
@@ -77,7 +77,7 @@ export default defineComponent({
77
77
 
78
78
  return {
79
79
  menu,
80
- menuData: computed<MenuItem[]>(() => [
80
+ menuData: computed<(MenuButton | MenuComponent)[]>(() => [
81
81
  {
82
82
  type: 'button',
83
83
  text: '新增',