CompController.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {reactive, computed} from "vue"
  2. import { DesignComp } from "../../defines/DesignTemp/DesignComp"
  3. import { cloneDeep } from "lodash";
  4. type CreateFunc = (values:any, comm?: Partial<CommPropType>)=>DesignComp;
  5. export class CompController{
  6. state = reactive({
  7. _id: "",
  8. title: "",
  9. pageStyle: {},
  10. content: [] as DesignComp[]
  11. })
  12. //包括所有部件和所有列表的
  13. designCompMap = new Map<string, DesignComp>();
  14. CompTypes = [] as {type:string, name:string, thumbnail:string, isBasic: boolean, createCompData: CreateFunc}[];
  15. initPageData(designData:any) {
  16. this.state._id = designData._id;
  17. this.state.title = designData.title;
  18. this.state.pageStyle = designData.pageStyle;
  19. this.state.content = designData.content || [];
  20. const arr = this.state.content;
  21. this.designCompMap.clear();
  22. const ParseComp = (obj:any)=> {
  23. if (typeof obj != "object") return;
  24. //作为组件
  25. if (obj.id && obj.compKey && obj.value) {
  26. this.designCompMap.set(obj.id, obj);
  27. } else {
  28. for (const c in obj) {
  29. ParseComp(obj[c]);
  30. }
  31. }
  32. }
  33. let index = arr.length
  34. while (index--) {
  35. const item = arr[index];
  36. ParseComp(item.value)
  37. this.designCompMap.set(item.id, item);
  38. }
  39. }
  40. insertDesignContent(compKey: string, index?: number) {
  41. index === undefined && (index = this.state.content.length);
  42. const comp = this.createCompData(compKey);
  43. if (!comp) return;
  44. this.state.content.push( comp );
  45. return comp;
  46. }
  47. insertCompContainer(compKey: string, container: DesignComp) {
  48. const compData = this.createCompData(compKey)
  49. if (!compData) {
  50. console.error("没有找到对应的组件")
  51. return;
  52. }
  53. container.value.children || (container.value.children = []);
  54. container.value.children.push( compData );
  55. return compData;
  56. }
  57. createCompData(compKey: string) {
  58. const CompType = this.CompTypes.find(item=>item.type == compKey);
  59. if (!CompType) return;
  60. return CompType.createCompData(this.isText(compKey) ? "": {});
  61. }
  62. isText(compKey:string) {
  63. return compKey == "Text";
  64. }
  65. getCompType(compKey:string) {
  66. return this.CompTypes.find(item=>item.type == compKey);
  67. }
  68. setCompState(compId: string , data:any) {
  69. this.designCompMap.set(compId, data);
  70. }
  71. getCompState(compId:string ) {
  72. return this.designCompMap.get(compId) as DesignComp;
  73. }
  74. }
  75. export const CompCtrl = new CompController();
  76. type CommPropType = Pick<DesignComp, "compKey" | "background" | "layout" | "id">
  77. export function RegCompType<T>(info: {type:string , name:string, thumbnail:string, isBasic?:boolean}, getDef:(Partial<CommPropType> & {value: T})|(()=>Partial<CommPropType> & {value: T})) {
  78. info.isBasic = info.isBasic ? true : false;
  79. const createCompData = function(values: Partial<T>, comm?: Partial<CommPropType>) {
  80. const defvalues = typeof getDef == "function" ? getDef(): cloneDeep(getDef);
  81. defvalues.compKey = info.type as any
  82. const isStrValue = (typeof values == "string" || typeof defvalues.value == "string");
  83. if (isStrValue && values) {
  84. //@ts-ignore
  85. defvalues.value = values;
  86. }
  87. const c = Object.assign({}, defvalues, comm) as CommPropType &{value: T}
  88. if (!isStrValue && values != null ) {
  89. c.value = {...c.value, ...values}
  90. }
  91. const ret = new DesignComp(c) as typeof c;
  92. const out = reactive(ret)
  93. CompCtrl.setCompState(ret.id, out);
  94. return out;
  95. }
  96. type ValueType = ReturnType<typeof createCompData>
  97. function useCompData(compId: string) {
  98. return CompCtrl.getCompState(compId) as ValueType;
  99. }
  100. //@ts-ignore
  101. info.createCompData = createCompData;
  102. if (!CompCtrl.CompTypes.find(item=>item.type == info.type)) {
  103. CompCtrl.CompTypes.push(info as any);
  104. }
  105. return {useCompData, createCompData}
  106. }