@tmagic/editor 1.1.0-beta.7 → 1.1.0

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 (63) hide show
  1. package/dist/style.css +50 -0
  2. package/dist/tmagic-editor.mjs +1198 -1027
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +1201 -1026
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +22 -6
  8. package/src/components/ContentMenu.vue +4 -4
  9. package/src/components/Icon.vue +7 -21
  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 +10 -13
  22. package/src/layouts/workspace/Workspace.vue +133 -138
  23. package/src/services/componentList.ts +5 -0
  24. package/src/services/editor.ts +201 -112
  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/component-list-panel.scss +5 -0
  30. package/src/theme/nav-menu.scss +6 -0
  31. package/src/type.ts +28 -11
  32. package/src/utils/editor.ts +17 -10
  33. package/src/utils/index.ts +1 -0
  34. package/src/utils/operator.ts +22 -123
  35. package/src/utils/props.ts +0 -3
  36. package/src/utils/scroll-viewer.ts +90 -158
  37. package/src/utils/stage.ts +91 -0
  38. package/types/Editor.vue.d.ts +17 -8
  39. package/types/components/ContentMenu.vue.d.ts +8 -8
  40. package/types/components/Icon.vue.d.ts +62 -12
  41. package/types/components/ScrollBar.vue.d.ts +83 -0
  42. package/types/components/ScrollViewer.vue.d.ts +131 -19
  43. package/types/components/ToolButton.vue.d.ts +56 -59
  44. package/types/index.d.ts +2 -0
  45. package/types/layouts/NavMenu.vue.d.ts +92 -23
  46. package/types/layouts/PropsPanel.vue.d.ts +25 -208
  47. package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
  48. package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
  49. package/types/layouts/workspace/ViewerMenu.vue.d.ts +3 -3
  50. package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
  51. package/types/services/componentList.d.ts +1 -0
  52. package/types/services/editor.d.ts +10 -17
  53. package/types/services/events.d.ts +1 -0
  54. package/types/services/props.d.ts +41 -9
  55. package/types/services/storage.d.ts +1 -0
  56. package/types/services/ui.d.ts +3 -1
  57. package/types/type.d.ts +25 -11
  58. package/types/utils/editor.d.ts +4 -1
  59. package/types/utils/index.d.ts +1 -0
  60. package/types/utils/operator.d.ts +3 -26
  61. package/types/utils/props.d.ts +0 -1
  62. package/types/utils/scroll-viewer.d.ts +16 -18
  63. package/types/utils/stage.d.ts +3 -0
@@ -32,14 +32,16 @@ import {
32
32
  change2Fixed,
33
33
  COPY_STORAGE_KEY,
34
34
  Fixed2Other,
35
+ fixNodePosition,
35
36
  getInitPositionStyle,
36
37
  getNodeIndex,
37
38
  isFixed,
38
39
  setLayout,
39
40
  } from '../utils/editor';
40
- import { beforeAdd, beforePaste, beforeRemove, notifyAddToStage } from '../utils/operator';
41
+ import { beforePaste, getAddParent } from '../utils/operator';
41
42
 
42
43
  import BaseService from './BaseService';
44
+ import propsService from './props';
43
45
 
44
46
  class Editor extends BaseService {
45
47
  public state: StoreState = reactive({
@@ -60,12 +62,17 @@ class Editor extends BaseService {
60
62
  [
61
63
  'getLayout',
62
64
  'select',
65
+ 'doAdd',
63
66
  'add',
67
+ 'doRemove',
64
68
  'remove',
69
+ 'doUpdate',
65
70
  'update',
66
71
  'sort',
67
72
  'copy',
68
73
  'paste',
74
+ 'doPaste',
75
+ 'duAlignCenter',
69
76
  'alignCenter',
70
77
  'moveLayer',
71
78
  'moveToContainer',
@@ -281,34 +288,40 @@ class Editor extends BaseService {
281
288
  this.set('nodes', nodes);
282
289
  }
283
290
 
284
- /**
285
- * 批量向容器添加节点
286
- * @param configs 将要添加的节点数组
287
- * @returns 添加后的节点
288
- */
289
- public async multiAdd(configs: MNode[]): Promise<MNode[]> {
291
+ public async doAdd(node: MNode, parent: MContainer): Promise<MNode> {
292
+ const root = this.get<MApp>('root');
293
+ const curNode = this.get<MNode>('node');
290
294
  const stage = this.get<StageCore | null>('stage');
291
- const newNodes: MNode[] = await Promise.all(
292
- configs.map(async (configItem: MNode): Promise<MNode> => {
293
- // 新增元素到配置
294
- const { parentNode, newNode, layout } = await beforeAdd(configItem as AddMNode);
295
- // 将新增元素事件通知到stage以更新渲染
296
- await notifyAddToStage(parentNode, newNode, layout);
297
- return newNode;
298
- }),
299
- );
300
- const newNodeIds: Id[] = newNodes.map((node) => node.id);
301
295
 
302
- // 增加历史记录 多选不可能选中page
303
- this.addModifiedNodeId(newNodeIds.join('-'));
304
- this.pushHistoryState();
296
+ if ((parent?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
297
+ throw new Error('app下不能添加组件');
298
+ }
299
+
300
+ if (parent.id !== curNode.id) {
301
+ const index = parent.items.indexOf(curNode);
302
+ parent?.items?.splice(index + 1, 0, node);
303
+ } else {
304
+ // 新增节点添加到配置中
305
+ parent?.items?.push(node);
306
+ }
307
+
308
+ const layout = await this.getLayout(toRaw(parent), node as MNode);
309
+ node.style = getInitPositionStyle(node.style, layout);
310
+
311
+ await stage?.add({
312
+ config: cloneDeep(node),
313
+ parent: cloneDeep(parent),
314
+ parentId: parent.id,
315
+ root: cloneDeep(root),
316
+ });
317
+
318
+ node.style = fixNodePosition(node, parent, stage);
305
319
 
306
- // 触发选中样式
307
- stage?.multiSelect(newNodeIds);
320
+ await stage?.update({ config: cloneDeep(node), parentId: parent.id, root: cloneDeep(root) });
308
321
 
309
- this.emit('multiAdd', newNodes);
322
+ this.addModifiedNodeId(node.id);
310
323
 
311
- return newNodes;
324
+ return node;
312
325
  }
313
326
 
314
327
  /**
@@ -317,30 +330,92 @@ class Editor extends BaseService {
317
330
  * @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
318
331
  * @returns 添加后的节点
319
332
  */
320
- public async add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode> {
333
+ public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
321
334
  const stage = this.get<StageCore | null>('stage');
322
- // 新增元素到配置
323
- const { parentNode, newNode, layout, isPage } = await beforeAdd(addNode, parent);
324
- // 将新增元素事件通知到stage以更新渲染
325
- await notifyAddToStage(parentNode, newNode, layout);
326
- // 更新编辑器选中元素
327
- await this.select(newNode);
328
- // 增加历史记录
329
- this.addModifiedNodeId(newNode.id);
330
- if (!isPage) {
331
- this.pushHistoryState();
335
+
336
+ // 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
337
+ const addNodes = [];
338
+ if (!Array.isArray(addNode)) {
339
+ const { type, inputEvent, ...config } = addNode;
340
+
341
+ if (!type) throw new Error('组件类型不能为空');
342
+
343
+ addNodes.push({ ...toRaw(await propsService.getPropsValue(type, config)) });
344
+ } else {
345
+ addNodes.push(...addNode);
332
346
  }
333
347
 
334
- if (isPage) {
335
- this.state.pageLength += 1;
348
+ const newNodes = await Promise.all(
349
+ addNodes.map((node) => {
350
+ const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(node);
351
+ if (!parentNode) throw new Error('未找到父元素');
352
+ return this.doAdd(node, parentNode);
353
+ }),
354
+ );
355
+
356
+ if (newNodes.length > 1) {
357
+ const newNodeIds = newNodes.map((node) => node.id);
358
+ // 触发选中样式
359
+ stage?.multiSelect(newNodeIds);
360
+ await this.multiSelect(newNodeIds);
336
361
  } else {
337
- // 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
338
- stage?.select(newNode.id);
362
+ await this.select(newNodes[0]);
363
+
364
+ if (isPage(newNodes[0])) {
365
+ this.state.pageLength += 1;
366
+ } else {
367
+ // 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
368
+ stage?.select(newNodes[0].id);
369
+ }
339
370
  }
340
371
 
341
- this.emit('add', newNode);
372
+ this.pushHistoryState();
342
373
 
343
- return newNode;
374
+ this.emit('add', newNodes);
375
+
376
+ return Array.isArray(addNode) ? newNodes : newNodes[0];
377
+ }
378
+
379
+ public async doRemove(node: MNode): Promise<void> {
380
+ const root = this.get<MApp | null>('root');
381
+
382
+ if (!root) throw new Error('没有root');
383
+
384
+ const { parent, node: curNode } = this.getNodeInfo(node.id);
385
+
386
+ if (!parent || !curNode) throw new Error('找不要删除的节点');
387
+
388
+ const index = getNodeIndex(curNode, parent);
389
+
390
+ if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
391
+
392
+ parent.items?.splice(index, 1);
393
+ const stage = this.get<StageCore | null>('stage');
394
+ stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
395
+
396
+ if (node.type === NodeType.PAGE) {
397
+ this.state.pageLength -= 1;
398
+
399
+ if (root.items[0]) {
400
+ await this.select(root.items[0]);
401
+ stage?.select(root.items[0].id);
402
+ } else {
403
+ this.set('node', null);
404
+ this.set('parent', null);
405
+ this.set('page', null);
406
+ this.set('stage', null);
407
+ this.set('highlightNode', null);
408
+ this.resetModifiedNodeId();
409
+ historyService.reset();
410
+
411
+ return;
412
+ }
413
+ } else {
414
+ await this.select(parent);
415
+ stage?.select(parent.id);
416
+ }
417
+
418
+ this.addModifiedNodeId(parent.id);
344
419
  }
345
420
 
346
421
  /**
@@ -348,50 +423,18 @@ class Editor extends BaseService {
348
423
  * @param {Object} node
349
424
  * @return {Object} 删除的组件配置
350
425
  */
351
- public async remove(nodeOrNodeList: MNode | MNode[]): Promise<MNode | MNode[]> {
352
- if (Array.isArray(nodeOrNodeList)) {
353
- // 多选批量删除
354
- const nodes = nodeOrNodeList;
355
- return this.multiRemove(nodes);
356
- }
357
- const node = nodeOrNodeList;
358
- const removeParent = await beforeRemove(node);
359
- // 删除的是页面
360
- if (!removeParent) return node;
361
- // 更新历史记录
362
- this.addModifiedNodeId(removeParent.id);
363
- this.pushHistoryState();
426
+ public async remove(nodeOrNodeList: MNode | MNode[]): Promise<void> {
427
+ const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
364
428
 
365
- this.emit('remove', node);
429
+ await Promise.all(nodes.map((node) => this.doRemove(node)));
366
430
 
367
- return node;
368
- }
369
-
370
- /**
371
- * 批量删除
372
- * @param nodes 批量删除的节点
373
- * @returns 批量删除的节点
374
- */
375
- public async multiRemove(nodes: MNode[]): Promise<MNode[]> {
376
- await Promise.all(
377
- nodes.map(async (removeNode) => {
378
- await beforeRemove(removeNode);
379
- }),
380
- );
381
- const nodeIds = nodes.map((node) => node.id);
382
- this.addModifiedNodeId(nodeIds.join('-'));
431
+ // 更新历史记录
383
432
  this.pushHistoryState();
384
433
 
385
- this.emit('multiRemove', nodes);
386
- return nodes;
434
+ this.emit('remove', nodes);
387
435
  }
388
436
 
389
- /**
390
- * 更新节点
391
- * @param config 新的节点配置,配置中需要有id信息
392
- * @returns 更新后的节点配置
393
- */
394
- public async update(config: MNode): Promise<MNode> {
437
+ public async doUpdate(config: MNode) {
395
438
  if (!config?.id) throw new Error('没有配置或者配置缺少id值');
396
439
 
397
440
  const info = this.getNodeInfo(config.id, false);
@@ -437,18 +480,36 @@ class Editor extends BaseService {
437
480
  nodes.splice(targetIndex, 1, newConfig);
438
481
  this.set('nodes', nodes);
439
482
 
440
- this.get<StageCore | null>('stage')?.update({ config: cloneDeep(newConfig), root: cloneDeep(this.get('root')) });
483
+ this.get<StageCore | null>('stage')?.update({
484
+ config: cloneDeep(newConfig),
485
+ parentId: parent.id,
486
+ root: cloneDeep(this.get('root')),
487
+ });
441
488
 
442
489
  if (newConfig.type === NodeType.PAGE) {
443
490
  this.set('page', newConfig);
444
491
  }
445
492
 
446
493
  this.addModifiedNodeId(newConfig.id);
494
+
495
+ return newConfig;
496
+ }
497
+
498
+ /**
499
+ * 更新节点
500
+ * @param config 新的节点配置,配置中需要有id信息
501
+ * @returns 更新后的节点配置
502
+ */
503
+ public async update(config: MNode | MNode[]): Promise<MNode | MNode[]> {
504
+ const nodes = Array.isArray(config) ? config : [config];
505
+
506
+ const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
507
+
447
508
  this.pushHistoryState();
448
509
 
449
- this.emit('update', newConfig);
510
+ this.emit('update', newNodes);
450
511
 
451
- return newConfig;
512
+ return Array.isArray(config) ? newNodes : newNodes[0];
452
513
  }
453
514
 
454
515
  /**
@@ -470,7 +531,11 @@ class Editor extends BaseService {
470
531
  await this.update(parent);
471
532
  await this.select(node);
472
533
 
473
- this.get<StageCore | null>('stage')?.update({ config: cloneDeep(node), root: cloneDeep(this.get('root')) });
534
+ this.get<StageCore | null>('stage')?.update({
535
+ config: cloneDeep(node),
536
+ parentId: parent.id,
537
+ root: cloneDeep(this.get('root')),
538
+ });
474
539
 
475
540
  this.addModifiedNodeId(parent.id);
476
541
  this.pushHistoryState();
@@ -492,30 +557,33 @@ class Editor extends BaseService {
492
557
  * @param position 粘贴的坐标
493
558
  * @returns 添加后的组件节点配置
494
559
  */
495
- public async paste(position: PastePosition = {}): Promise<MNode[] | void> {
496
- const config = await storageService.getItem(COPY_STORAGE_KEY);
560
+ public async paste(position: PastePosition = {}): Promise<MNode | MNode[] | void> {
561
+ const config: MNode[] = await storageService.getItem(COPY_STORAGE_KEY);
497
562
 
498
- if (!config) return;
563
+ if (!Array.isArray(config)) return;
499
564
 
500
- const pasteConfigs = await beforePaste(position, config);
565
+ const pasteConfigs = await this.doPaste(config, position);
501
566
 
502
- return await this.multiAdd(pasteConfigs);
567
+ return this.add(pasteConfigs);
503
568
  }
504
569
 
505
- /**
506
- * 将指点节点设置居中
507
- * @param config 组件节点配置
508
- * @returns 当前组件节点配置
509
- */
510
- public async alignCenter(config: MNode): Promise<MNode | void> {
511
- const parent = this.get<MContainer>('parent');
512
- const node = this.get<MNode>('node');
513
- const layout = await this.getLayout(toRaw(parent), toRaw(node));
570
+ public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
571
+ const pasteConfigs = await beforePaste(position, cloneDeep(config));
572
+ return pasteConfigs;
573
+ }
574
+
575
+ public async doAlignCenter(config: MNode): Promise<MNode> {
576
+ const parent = this.getParentById(config.id);
577
+
578
+ if (!parent) throw new Error('找不到父节点');
579
+
580
+ const node = cloneDeep(toRaw(config));
581
+ const layout = await this.getLayout(parent, node);
514
582
  if (layout === Layout.RELATIVE) {
515
- return;
583
+ return config;
516
584
  }
517
585
 
518
- if (!node.style) return;
586
+ if (!node.style) return config;
519
587
 
520
588
  const stage = this.get<StageCore>('stage');
521
589
  const doc = stage?.renderer.contentWindow?.document;
@@ -530,15 +598,25 @@ class Editor extends BaseService {
530
598
  node.style.left = (parent.style.width - node.style.width) / 2;
531
599
  }
532
600
 
533
- await this.update(node);
534
- this.get<StageCore | null>('stage')?.update({
535
- config: cloneDeep(toRaw(node)),
536
- root: cloneDeep(this.get<MApp>('root')),
537
- });
538
- this.addModifiedNodeId(config.id);
539
- this.pushHistoryState();
601
+ return node;
602
+ }
540
603
 
541
- return config;
604
+ /**
605
+ * 将指点节点设置居中
606
+ * @param config 组件节点配置
607
+ * @returns 当前组件节点配置
608
+ */
609
+ public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
610
+ const nodes = Array.isArray(config) ? config : [config];
611
+ const stage = this.get<StageCore | null>('stage');
612
+
613
+ const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
614
+
615
+ const newNode = await this.update(newNodes);
616
+
617
+ await stage?.multiSelect(newNodes.map((node) => node.id));
618
+
619
+ return newNode;
542
620
  }
543
621
 
544
622
  /**
@@ -547,7 +625,7 @@ class Editor extends BaseService {
547
625
  */
548
626
  public async moveLayer(offset: number | LayerOffset): Promise<void> {
549
627
  const parent = this.get<MContainer>('parent');
550
- const node = this.get('node');
628
+ const node = this.get<MNode>('node');
551
629
  const brothers: MNode[] = parent?.items || [];
552
630
  const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
553
631
 
@@ -559,10 +637,15 @@ class Editor extends BaseService {
559
637
  brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
560
638
  }
561
639
 
640
+ const grandparent = this.getParentById(parent.id);
562
641
  this.get<StageCore | null>('stage')?.update({
563
642
  config: cloneDeep(toRaw(parent)),
643
+ parentId: grandparent?.id,
564
644
  root: cloneDeep(this.get<MApp>('root')),
565
645
  });
646
+
647
+ this.addModifiedNodeId(parent.id);
648
+ this.pushHistoryState();
566
649
  }
567
650
 
568
651
  /**
@@ -581,7 +664,7 @@ class Editor extends BaseService {
581
664
  const index = getNodeIndex(node, parent);
582
665
  parent.items?.splice(index, 1);
583
666
 
584
- await stage.remove({ id: node.id, root });
667
+ await stage.remove({ id: node.id, parentId: parent.id, root });
585
668
 
586
669
  const layout = await this.getLayout(target);
587
670
 
@@ -590,13 +673,14 @@ class Editor extends BaseService {
590
673
  return srcValue;
591
674
  }
592
675
  });
593
- newConfig.style = getInitPositionStyle(newConfig.style, layout, target, stage);
676
+ newConfig.style = getInitPositionStyle(newConfig.style, layout);
594
677
 
595
678
  target.items.push(newConfig);
596
679
 
597
680
  await stage.select(targetId);
598
681
 
599
- await stage.update({ config: cloneDeep(target), root });
682
+ const targetParent = this.getParentById(target.id);
683
+ await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root });
600
684
 
601
685
  await this.select(newConfig);
602
686
  stage.select(newConfig.id);
@@ -633,7 +717,7 @@ class Editor extends BaseService {
633
717
  const node = toRaw(this.get('node'));
634
718
  if (!node || isPage(node)) return;
635
719
 
636
- const { style, id } = node;
720
+ const { style, id, type } = node;
637
721
  if (!style || style.position !== 'absolute') return;
638
722
 
639
723
  if (top && !isNumber(style.top)) return;
@@ -641,6 +725,7 @@ class Editor extends BaseService {
641
725
 
642
726
  this.update({
643
727
  id,
728
+ type,
644
729
  style: {
645
730
  ...style,
646
731
  left: Number(style.left) + left,
@@ -656,6 +741,10 @@ class Editor extends BaseService {
656
741
  this.set('nodes', []);
657
742
  this.set('page', null);
658
743
  this.set('parent', null);
744
+ this.set('stage', null);
745
+ this.set('highlightNode', null);
746
+ this.set('modifiedNodeIds', new Map());
747
+ this.set('pageLength', new Map());
659
748
  }
660
749
 
661
750
  public resetModifiedNodeId() {
@@ -26,8 +26,8 @@ import type { ComponentGroup } from '../type';
26
26
 
27
27
  import BaseService from './BaseService';
28
28
 
29
- const eventMap: Record<string, EventOption[]> = reactive({});
30
- const methodMap: Record<string, EventOption[]> = reactive({});
29
+ let eventMap: Record<string, EventOption[]> = reactive({});
30
+ let methodMap: Record<string, EventOption[]> = reactive({});
31
31
 
32
32
  class Events extends BaseService {
33
33
  constructor() {
@@ -75,6 +75,12 @@ class Events extends BaseService {
75
75
  public getMethod(type: string) {
76
76
  return cloneDeep(methodMap[type] || DEFAULT_METHODS);
77
77
  }
78
+
79
+ public destroy() {
80
+ eventMap = reactive({});
81
+ methodMap = reactive({});
82
+ this.removeAllListeners();
83
+ }
78
84
  }
79
85
 
80
86
  export type EventsService = Events;
@@ -20,12 +20,11 @@ import { reactive } from 'vue';
20
20
  import { cloneDeep, mergeWith } from 'lodash-es';
21
21
 
22
22
  import type { FormConfig } from '@tmagic/form';
23
- import type { Id, MComponent, MNode, MPage } from '@tmagic/schema';
24
- import { NodeType } from '@tmagic/schema';
25
- import { isPop, toLine } from '@tmagic/utils';
23
+ import type { MComponent, MNode } from '@tmagic/schema';
24
+ import { toLine } from '@tmagic/utils';
26
25
 
27
26
  import type { PropsState } from '../type';
28
- import { DEFAULT_CONFIG, fillConfig } from '../utils/props';
27
+ import { fillConfig } from '../utils/props';
29
28
 
30
29
  import BaseService from './BaseService';
31
30
 
@@ -43,6 +42,7 @@ class Props extends BaseService {
43
42
  'getPropsValue',
44
43
  'createId',
45
44
  'setNewItemId',
45
+ 'fillConfig',
46
46
  'getDefaultPropsValue',
47
47
  ]);
48
48
  }
@@ -54,13 +54,17 @@ class Props extends BaseService {
54
54
  this.emit('props-configs-change');
55
55
  }
56
56
 
57
+ public async fillConfig(config: FormConfig) {
58
+ return fillConfig(config);
59
+ }
60
+
57
61
  /**
58
62
  * 为指定类型组件设置组件属性表单配置
59
63
  * @param type 组件类型
60
64
  * @param config 组件属性表单配置
61
65
  */
62
- public setPropsConfig(type: string, config: FormConfig) {
63
- this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
66
+ public async setPropsConfig(type: string, config: FormConfig) {
67
+ this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
64
68
  }
65
69
 
66
70
  /**
@@ -73,7 +77,7 @@ class Props extends BaseService {
73
77
  return await this.getPropsConfig('button');
74
78
  }
75
79
 
76
- return cloneDeep(this.state.propsConfigMap[type] || DEFAULT_CONFIG);
80
+ return cloneDeep(this.state.propsConfigMap[type] || (await this.fillConfig([])));
77
81
  }
78
82
 
79
83
  public setPropsValues(values: Record<string, MNode>) {
@@ -125,19 +129,6 @@ class Props extends BaseService {
125
129
  };
126
130
  }
127
131
 
128
- /**
129
- * 生成指定位数的GUID,无【-】格式
130
- * @param digit 位数,默认值8
131
- * @returns
132
- */
133
- guid(digit = 8): string {
134
- return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
135
- const r = (Math.random() * 16) | 0;
136
- const v = c == 'x' ? r : (r & 0x3) | 0x8;
137
- return v.toString(16);
138
- });
139
- }
140
-
141
132
  public async createId(type: string | number): Promise<string> {
142
133
  return `${type}_${this.guid()}`;
143
134
  }
@@ -147,19 +138,12 @@ class Props extends BaseService {
147
138
  * @param {Object} config 组件配置
148
139
  */
149
140
  /* eslint no-param-reassign: ["error", { "props": false }] */
150
- public async setNewItemId(config: MNode, parent?: MPage) {
151
- const oldId = config.id;
152
-
141
+ public async setNewItemId(config: MNode) {
153
142
  config.id = await this.createId(config.type || 'component');
154
143
 
155
- // 只有弹窗在页面下的一级子元素才有效
156
- if (isPop(config) && parent?.type === NodeType.PAGE) {
157
- updatePopId(oldId, config.id, parent);
158
- }
159
-
160
144
  if (config.items && Array.isArray(config.items)) {
161
145
  for (const item of config.items) {
162
- await this.setNewItemId(item, config as MPage);
146
+ await this.setNewItemId(item);
163
147
  }
164
148
  }
165
149
 
@@ -186,31 +170,26 @@ class Props extends BaseService {
186
170
  name: type,
187
171
  };
188
172
  }
189
- }
190
173
 
191
- /**
192
- * 复制页面时,需要把组件下关联的弹窗id换测复制出来的弹窗的id
193
- * @param {number} oldId 复制的源弹窗id
194
- * @param {number} popId 新的弹窗id
195
- * @param {Object} pageConfig 页面配置
196
- */
197
- const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
198
- pageConfig.items?.forEach((config) => {
199
- if (config.pop === oldId) {
200
- config.pop = popId;
201
- return;
202
- }
203
-
204
- if (config.popId === oldId) {
205
- config.popId = popId;
206
- return;
207
- }
174
+ public destroy() {
175
+ this.state.propsConfigMap = {};
176
+ this.state.propsValueMap = {};
177
+ this.removeAllListeners();
178
+ }
208
179
 
209
- if (Array.isArray(config.items)) {
210
- updatePopId(oldId, popId, config as MPage);
211
- }
212
- });
213
- };
180
+ /**
181
+ * 生成指定位数的GUID,无【-】格式
182
+ * @param digit 位数,默认值8
183
+ * @returns
184
+ */
185
+ private guid(digit = 8): string {
186
+ return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
187
+ const r = (Math.random() * 16) | 0;
188
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
189
+ return v.toString(16);
190
+ });
191
+ }
192
+ }
214
193
 
215
194
  export type PropsService = Props;
216
195
 
@@ -107,6 +107,10 @@ export class WebStorage extends BaseService {
107
107
  storage.setItem(`${options.namespace || namespace}:${key}`, item);
108
108
  }
109
109
 
110
+ public destroy() {
111
+ this.removeAllListeners();
112
+ }
113
+
110
114
  private getValueAndProtocol(value: string | null) {
111
115
  let protocol = '';
112
116