@cloudbase/framework-plugin-low-code 0.6.17 → 0.6.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,uBAAuB,EAKxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,QAAQ,CAAC,OAanD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE;;;EAa1E;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,UAsDnD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,GAAG,EAAE,aAAa,MA4BnB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,MAqFnB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,GAAG,EAAE,aAAa,MAuDnB"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,uBAAuB,EAKxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,QAAQ,CAAC,OAanD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE;;;EAa1E;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,UAsDnD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,GAAG,EAAE,aAAa,MA4BnB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,MAmGnB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,GAAG,EAAE,aAAa,MAuDnB"}
@@ -109,7 +109,7 @@ exports.createWidgetProps = createWidgetProps;
109
109
  function createEventHanlders(widgets, componentApi, ctx) {
110
110
  const eventHanlders = {};
111
111
  weapp_1.walkThroughWidgets(widgets, (id, widget, parentId) => {
112
- var _a, _b;
112
+ var _a, _b, _c;
113
113
  const { xComponent } = widget;
114
114
  const xProps = widget.xProps || {};
115
115
  if (!xComponent) {
@@ -174,6 +174,18 @@ function createEventHanlders(widgets, componentApi, ctx) {
174
174
  type: l.type,
175
175
  });
176
176
  });
177
+ if ((_c = compProto === null || compProto === void 0 ? void 0 : compProto.compConfig) === null || _c === void 0 ? void 0 : _c.isDataContainer) {
178
+ const customName = wxml_1.getMpEventHanlderName(id, 'onDataChange', {});
179
+ eventHanlders[customName] = [{
180
+ key: `wa${Date.now().toString().slice(-8)}`,
181
+ handler: `({event}) => {
182
+ app.utils.set(context, '${id}.data', event?.detail?.data);
183
+ }`,
184
+ handlerModule: weapps_core_1.ActionType.Platform,
185
+ data: {},
186
+ boundData: {},
187
+ }];
188
+ }
177
189
  });
178
190
  return eventHanlders;
179
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wxml.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/wxml.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,uBAAuB,EAEvB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,wBAAgB,YAAY,CAC1B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,MAAM,EAAE,MAAM,EACd,cAAc,KAAA,EACd,GAAG,EAAE,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EACxC,eAAe,KAAA,EACf,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,EAAE,IAAI,KAAA,KAAK,IAAI,UA8U7D;AA4BD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,eAAoB,UAS/B;AAuBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,QAAQ,GAAE;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;CAAO;;EAYlD"}
1
+ {"version":3,"file":"wxml.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/wxml.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,uBAAuB,EAEvB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,wBAAgB,YAAY,CAC1B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,MAAM,EAAE,MAAM,EACd,cAAc,KAAA,EACd,GAAG,EAAE,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EACxC,eAAe,KAAA,EACf,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,EAAE,IAAI,KAAA,KAAK,IAAI,UAqV7D;AA4BD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,eAAoB,UAS/B;AAuBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,EACnD,QAAQ,GAAE;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;CAAO;;EAYlD"}
@@ -194,6 +194,9 @@ function generateWxml(widgets, docTag, wxmlDataPrefix, ctx, usingComponents, nod
194
194
  getMpEventHanlderName(id, evtName, modifiers);
195
195
  });
196
196
  const compConfig = componentProto.compConfig;
197
+ if (compConfig === null || compConfig === void 0 ? void 0 : compConfig.isDataContainer) {
198
+ node.attributes['bind:onDataChange'] = getMpEventHanlderName(id, 'onDataChange');
199
+ }
197
200
  if (compConfig && compConfig.pluginConfig) {
198
201
  if (compConfig.pluginConfig.attributes) {
199
202
  Object.assign(node.attributes, compConfig.pluginConfig.attributes);
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../src/builder/service/builder/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../src/builder/service/builder/generate.ts"],"names":[],"mappings":"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"}
@@ -254,22 +254,25 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
254
254
  const compWidgets = {};
255
255
  const compDataBinds = {};
256
256
  const componentSchemaJson = util_1.deepDealSchema(copyJson, (schema) => {
257
- var _a, _b, _c, _d, _e, _f, _g, _h;
257
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
258
258
  const { 'x-props': xProps = {}, properties } = schema;
259
259
  const { dataBinds = [], commonStyle = {}, data = {}, classNameList = [], sourceKey, styleBind, classNameListBind, staticResourceAttribute = [], } = xProps;
260
260
  const componentInfo = componentsInfoMap[sourceKey];
261
261
  if ((_a = componentInfo) === null || _a === void 0 ? void 0 : _a.selectableBlock) {
262
262
  schema['selectableBlock'] = componentInfo['selectableBlock'];
263
263
  }
264
- if ((_b = componentInfo) === null || _b === void 0 ? void 0 : _b.events) {
265
- schema['emitEvents'] = (_c = componentInfo) === null || _c === void 0 ? void 0 : _c.events.map((item) => item.name);
264
+ if ((_b = componentInfo) === null || _b === void 0 ? void 0 : _b.compConfig) {
265
+ schema['compConfig'] = componentInfo['compConfig'];
266
266
  }
267
- else if ((_d = componentInfo) === null || _d === void 0 ? void 0 : _d.emitEvents) {
267
+ if ((_c = componentInfo) === null || _c === void 0 ? void 0 : _c.events) {
268
+ schema['emitEvents'] = (_d = componentInfo) === null || _d === void 0 ? void 0 : _d.events.map((item) => item.name);
269
+ }
270
+ else if ((_e = componentInfo) === null || _e === void 0 ? void 0 : _e.emitEvents) {
268
271
  schema['emitEvents'] = componentInfo.emitEvents.map((item) => item.eventName);
269
272
  }
270
273
  if (!isSlot(schema) && schema.key) {
271
274
  compWidgets[schema.key] = Object.assign(Object.assign({}, data), { style: weapps_core_1.toCssStyle(commonStyle), classList: classNameList, widgetType: sourceKey, _parentId: isSlot(schema.parent)
272
- ? (_f = (_e = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _e === void 0 ? void 0 : _e.parent) === null || _f === void 0 ? void 0 : _f.key : (_g = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _g === void 0 ? void 0 : _g.key });
275
+ ? (_g = (_f = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _f === void 0 ? void 0 : _f.parent) === null || _g === void 0 ? void 0 : _g.key : (_h = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _h === void 0 ? void 0 : _h.key });
273
276
  if (dataBinds.length > 0) {
274
277
  compDataBinds[schema.key] = generateDataBinds(dataBinds, isComposite);
275
278
  }
@@ -310,7 +313,7 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
310
313
  }
311
314
  if (xProps) {
312
315
  if (isComposite) {
313
- if (!((_h = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _h === void 0 ? void 0 : _h.parent)) {
316
+ if (!((_j = schema === null || schema === void 0 ? void 0 : schema.parent) === null || _j === void 0 ? void 0 : _j.parent)) {
314
317
  if (!xProps['classNameList'])
315
318
  xProps['classNameList'] = [];
316
319
  xProps['classNameList'].push(wrapperClass);
@@ -363,7 +366,7 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
363
366
  syncPropArr.forEach(({ changeEvent, valueFromEvent }) => {
364
367
  xProps.listenerInstances.unshift({
365
368
  trigger: changeEvent,
366
- instanceFunction: `${config_1.REPLACE_SIGN}function({ event, forItems }) {
369
+ instanceFunction: `${config_1.REPLACE_SIGN}function({ event, forItems, $context }) {
367
370
  const $for = forItems;
368
371
  const wid = ${isComposite ? 'this.widgets' : '$page.widgets'}.${schema.key};
369
372
  const widgetData = (forItems.forIndexes && forItems.forIndexes.length > 0) ? get(wid, forItems.forIndexes) : wid;
@@ -408,12 +411,12 @@ function generateDataBinds(dataBinds, isComposite) {
408
411
  else if (bind.type === weapps_core_1.PropBindType.expression) {
409
412
  let code = bind.bindDataPath;
410
413
  if (isComposite) {
411
- funcCode = `(forItems) => { const $for = forItems; return (${code.replace(/\$comp/g, 'this.$WEAPPS_COMP')})}`;
414
+ funcCode = `(forItems, event, $context) => { const $for = forItems; return (${code.replace(/\$comp/g, 'this.$WEAPPS_COMP')})}`;
412
415
  }
413
416
  else {
414
417
  funcCode = /\$scope\./.test(code)
415
- ? `(forItems, event) => ({__type: "scopedValue", getValue: ($scope) => { const $for = forItems;return (\n${code}\n)}})`
416
- : `(forItems, event) => { const $for = forItems;return (\n${code}\n)}`;
418
+ ? `(forItems, event, $context) => ({__type: "scopedValue", getValue: ($scope) => { const $for = forItems; return (\n${code}\n)}})`
419
+ : `(forItems, event, $context) => { const $for = forItems; return (\n${code}\n)}`;
417
420
  }
418
421
  }
419
422
  else if (bind.type === weapps_core_1.PropBindType.prop) {
@@ -141,7 +141,7 @@ function getComponentsInfo(appBuildDir, dependencies) {
141
141
  name,
142
142
  meta: yield fs_extra_1.default.readJson(componentMetaPath),
143
143
  };
144
- outputObj[sourceKey] = Object.assign({ isComposite }, metaJson);
144
+ outputObj[sourceKey] = Object.assign(Object.assign({ isComposite }, metaJson), { compConfig: {} });
145
145
  })));
146
146
  }
147
147
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/generator/core/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/generator/core/generate.ts"],"names":[],"mappings":"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"}
@@ -202,23 +202,26 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
202
202
  const compWidgets = {};
203
203
  const compDataBinds = {};
204
204
  const componentSchemaJson = util_1.deepDealSchema(copyJson, (schema) => {
205
- var _a, _b, _c, _d, _e, _f;
205
+ var _a, _b, _c, _d, _e, _f, _g;
206
206
  const { 'x-props': xProps = {}, properties } = schema;
207
207
  const { dataBinds = [], commonStyle = {}, data = {}, classNameList = [], sourceKey, styleBind, classNameListBind, } = xProps;
208
208
  const componentInfo = componentsInfoMap[sourceKey];
209
209
  if ((_a = componentInfo) === null || _a === void 0 ? void 0 : _a.selectableBlock) {
210
210
  schema['selectableBlock'] = componentInfo['selectableBlock'];
211
211
  }
212
- if ((_b = componentInfo) === null || _b === void 0 ? void 0 : _b.events) {
213
- schema['emitEvents'] = (_c = componentInfo) === null || _c === void 0 ? void 0 : _c.events.map((item) => item.name);
212
+ if ((_b = componentInfo) === null || _b === void 0 ? void 0 : _b.compConfig) {
213
+ schema['compConfig'] = componentInfo['compConfig'];
214
214
  }
215
- else if ((_d = componentInfo) === null || _d === void 0 ? void 0 : _d.emitEvents) {
215
+ if ((_c = componentInfo) === null || _c === void 0 ? void 0 : _c.events) {
216
+ schema['emitEvents'] = (_d = componentInfo) === null || _d === void 0 ? void 0 : _d.events.map((item) => item.name);
217
+ }
218
+ else if ((_e = componentInfo) === null || _e === void 0 ? void 0 : _e.emitEvents) {
216
219
  schema['emitEvents'] = componentInfo.emitEvents.map((item) => item.eventName);
217
220
  }
218
221
  if (!isSlot(schema) && schema.key) {
219
222
  const parentSchema = schema.parent;
220
223
  compWidgets[schema.key] = Object.assign(Object.assign({}, data), { style: weapps_core_1.toCssStyle(commonStyle), classList: classNameList, widgetType: sourceKey, _parentId: isSlot(parentSchema)
221
- ? (_e = parentSchema.parent) === null || _e === void 0 ? void 0 : _e.key : parentSchema.key });
224
+ ? (_f = parentSchema.parent) === null || _f === void 0 ? void 0 : _f.key : parentSchema.key });
222
225
  if (dataBinds.length > 0) {
223
226
  compDataBinds[schema.key] = generateDataBinds(dataBinds, isComposite);
224
227
  }
@@ -264,7 +267,7 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
264
267
  }
265
268
  if (xProps) {
266
269
  if (isComposite) {
267
- if (!((_f = schema.parent) === null || _f === void 0 ? void 0 : _f.parent)) {
270
+ if (!((_g = schema.parent) === null || _g === void 0 ? void 0 : _g.parent)) {
268
271
  if (!xProps['classNameList'])
269
272
  xProps['classNameList'] = [];
270
273
  xProps['classNameList'].push(wrapperClass);
@@ -312,7 +315,7 @@ function getComponentSchemaString(componentSchema, isComposite = false, componen
312
315
  syncPropArr.forEach(({ changeEvent, valueFromEvent }) => {
313
316
  xProps.listenerInstances.unshift({
314
317
  trigger: changeEvent,
315
- instanceFunction: `${config_1.REPLACE_SIGN}function({ event, forItems }) {
318
+ instanceFunction: `${config_1.REPLACE_SIGN}function({ event, forItems, $context }) {
316
319
  const $for = forItems;
317
320
  const wid = ${isComposite ? 'this.widgets' : '$page.widgets'}.${schema.key};
318
321
  const widgetData = (forItems.forIndexes && forItems.forIndexes.length > 0) ? get(wid, forItems.forIndexes) : wid;
@@ -357,15 +360,15 @@ function generateDataBinds(dataBinds, isComposite) {
357
360
  }
358
361
  else if (bind.type === weapps_core_1.PropBindType.expression) {
359
362
  if (isComposite) {
360
- funcCode = `(forItems) => {const $for = forItems; return (${bind.bindDataPath
363
+ funcCode = `(forItems, event, $context) => {const $for = forItems; return (${bind.bindDataPath
361
364
  .replace(/\$comp/g, 'this.$WEAPPS_COMP')
362
365
  .replace(/;$/, '')})}`;
363
366
  }
364
367
  else {
365
368
  const code = bind.bindDataPath.replace(/;$/, '');
366
369
  funcCode = /\$scope\./.test(code)
367
- ? `(forItems, event) => ({__type: "scopedValue", getValue: ($scope) => { const $for = forItems;return (${code})}})`
368
- : `(forItems, event) => { const $for = forItems;return (${code})}`;
370
+ ? `(forItems, event, $context)) => ({__type: "scopedValue", getValue: ($scope) => { const $for = forItems; return (${code})}})`
371
+ : `(forItems, event, $context)) => { const $for = forItems; return (${code})}`;
369
372
  }
370
373
  }
371
374
  else if (bind.type === weapps_core_1.PropBindType.prop) {
@@ -23,10 +23,10 @@ exports.default = {
23
23
  "code": "import { setConfig, initTcb, CLOUD_SDK } from '@cloudbase/weda-cloud-sdk/dist/h5';\nimport config from './config';\nexport {\n createDataset,\n createStateDataSourceVar,\n generateParamsParser,\n EXTRA_API,\n CLOUD_SDK,\n DS_API,\n DS_SDK,\n} from '@cloudbase/weda-cloud-sdk/dist/h5';\n\nsetConfig(config);\ninitTcb();\n"
24
24
  },
25
25
  "/src/handlers/NodeRenderer.jsx": {
26
- "code": "import * as React from 'react';\nimport {\n useContext,\n useCallback,\n createContext,\n useState,\n useRef,\n} from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { emitEvent, translateStyleToRem, checkVisible } from '../utils';\nimport { get, set } from 'lodash';\nimport { getDom } from '../utils/widgets';\n\nexport const ForContext = createContext({});\n\nexport const CompRenderer = observer(function (props) {\n const {\n id: compId,\n xProps,\n virtualFields,\n slots = {},\n codeContext = {},\n scopeContext = {},\n genericComp = {},\n emitEvents = [],\n componentSchema = {},\n } = props;\n\n const [blockIndex, setBlockIndex] = useState();\n const [blockType, setBlockType] = useState();\n const indexRef = useRef();\n const typeRef = useRef();\n indexRef.current = blockIndex;\n typeRef.current = blockType;\n\n const isInComposite = !!codeContext.$WEAPPS_COMP;\n // 判断 widgets 是从 page 来的,还是组件来的\n const widgetsData = !isInComposite\n ? codeContext.$page.widgets[compId]\n : codeContext.$WEAPPS_COMP.widgets[compId];\n\n const isRootNode = widgetsData && !widgetsData.parent;\n\n if (!xProps) {\n return props.children;\n }\n\n const {\n commonStyle = {},\n sourceKey,\n listenerInstances,\n classNameList = [],\n staticResourceAttribute = [],\n } = xProps;\n const dataBinds =\n (codeContext._dataBinds && codeContext._dataBinds[compId]) || {};\n const FieldKey = genericComp.propName\n ? codeContext.node[genericComp.propName]\n : sourceKey;\n const Field = virtualFields[FieldKey];\n const parentForItems = useContext(ForContext);\n\n // 组件最终用于执行的事件函数\n const emit = useCallback(\n (trigger, eventData, forItems, domEvent, scopeContext) => {\n const listeners = listenerInstances;\n const event = {\n detail: eventData,\n name: trigger,\n target: widgetsData,\n currentTarget: widgetsData,\n domEvent,\n };\n forItems = {\n ...forItems,\n forIndexes: getForIndexes(forItems, widgetsData),\n };\n emitEvent(\n trigger,\n listeners,\n {\n event,\n customEventData: event,\n forItems,\n domEvent,\n },\n scopeContext\n );\n },\n [props]\n );\n\n // 选区最终用于执行的事件函数\n const emitSB = useCallback(\n (trigger, eventData, forItems, domEvent, scopeContext, fieldData) => {\n const listeners =\n typeRef?.current &&\n indexRef?.current !== undefined &&\n fieldData?.[typeRef.current]?.[indexRef.current]?.selectableBlock?.[\n 'x-props'\n ]?.listenerInstances;\n const event = {\n detail: eventData,\n name: trigger,\n target: widgetsData,\n currentTarget: widgetsData,\n domEvent,\n };\n forItems = {\n ...forItems,\n forIndexes: getForIndexes(forItems, widgetsData),\n };\n emitEvent(\n trigger,\n listeners,\n {\n event,\n customEventData: event,\n forItems,\n domEvent,\n },\n scopeContext\n );\n },\n [props]\n );\n\n function getSafeComponentProps({\n style,\n classNameList,\n staticResourceAttribute,\n }) {\n const componentProps = {};\n if (classNameList.length) {\n componentProps.className = classNameList.join(' ');\n }\n\n if (style && Object.keys(style).length) {\n componentProps.style = style;\n }\n\n if (staticResourceAttribute && staticResourceAttribute.length > 0) {\n componentProps.staticResourceAttribute = staticResourceAttribute;\n }\n return componentProps;\n }\n\n // 选区的预览的click事件\n const onCustomEvent = ({ order: index, blockKey }) => {\n if (index !== undefined) {\n setBlockIndex(index);\n setBlockType(blockKey);\n }\n };\n\n // For循环渲染\n let forList;\n try {\n forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems);\n } catch (e) {\n forList = [];\n console.error('_waFor data', e);\n }\n if (forList) {\n if (!Array.isArray(forList)) {\n console.warn(`${compId}循环绑定非数组值:`, forList);\n forList = [];\n }\n return forList.map((item, index) => {\n const forItemsIndexes = (parentForItems.forIndexes || []).concat(index);\n const forItems = {\n ...parentForItems,\n [compId]: item,\n forIndexes: forItemsIndexes,\n };\n const {\n fieldData: forItemData,\n finalStyle: forItemStyle,\n finalClassNameList: forItemClassNameList,\n } = getBindData(forItems, scopeContext);\n if (!checkVisible(forItemData)) {\n return null;\n }\n // 多个组件的 slot 属性\n Object.keys(slots).forEach((slotProp) => {\n set(forItemData, slotProp, slots[slotProp]);\n });\n const emitWithForItems = (trigger, eventData, domEvent) =>\n emit(trigger, eventData, forItems, domEvent, scopeContext);\n\n const _selectableBlockEventsForItems = {\n onCustomEvent,\n events:\n componentSchema?.selectableBlock?.events.map((item) => item.name) ||\n [],\n emit: (trigger, eventData, domEvent) =>\n emitSB(\n trigger,\n eventData,\n forItems,\n domEvent,\n scopeContext,\n forItemData\n ),\n };\n\n delete forItemData.style;\n\n // 获取当前元素的 ref\n const currentWidget = Array.isArray(widgetsData)\n ? get(widgetsData, forItemsIndexes)\n : widgetsData;\n const domRef = setGetDomApi(currentWidget, props);\n return (\n <ForContext.Provider key={index} value={forItems}>\n <Field\n data={{\n ...forItemData,\n _selectableBlockEvents: _selectableBlockEventsForItems,\n }}\n id={compId}\n {...getSafeComponentProps({\n style: forItemStyle,\n classNameList: forItemClassNameList,\n staticResourceAttribute,\n })}\n emit={emitWithForItems}\n events={emitEvents}\n compositeParent={codeContext}\n forIndexes={forItemsIndexes}\n $node={currentWidget}\n domRef={domRef}\n >\n {props.children}\n </Field>\n </ForContext.Provider>\n );\n });\n }\n\n // 单节点渲染\n const { fieldData, finalClassNameList, finalStyle } = getBindData(\n parentForItems,\n scopeContext\n );\n const emitWithFiedle = (trigger, eventData, domEvent) =>\n emit(trigger, eventData, parentForItems, domEvent, scopeContext);\n\n const _selectableBlockEventsWithFiedle = {\n onCustomEvent,\n events:\n componentSchema?.selectableBlock?.events.map((item) => item.name) || [],\n emit: (trigger, eventData, domEvent) =>\n emitSB(\n trigger,\n eventData,\n parentForItems,\n domEvent,\n scopeContext,\n fieldData\n ),\n };\n\n // false 或空字符串时\n if (!checkVisible(fieldData)) {\n return null;\n }\n\n // 单个组件的 slot 属性\n Object.keys(slots).forEach((slotProp) => {\n set(fieldData, slotProp, slots[slotProp]);\n });\n\n // 防止渲染时 data 的 style 与实际的 style 冲突\n delete fieldData.style;\n\n // 修正 forIndexes\n const forIndexes = getForIndexes(parentForItems, widgetsData);\n\n // 获取 Element Ref\n const currentWidget = Array.isArray(widgetsData)\n ? get(widgetsData, forIndexes)\n : widgetsData;\n const domRef = setGetDomApi(currentWidget, props);\n\n return (\n <Field\n data={{\n ...fieldData,\n _selectableBlockEvents: _selectableBlockEventsWithFiedle,\n }}\n id={compId}\n {...getSafeComponentProps({\n style: finalStyle,\n classNameList: finalClassNameList,\n staticResourceAttribute,\n })}\n emit={emitWithFiedle}\n events={emitEvents}\n compositeParent={codeContext}\n forIndexes={forIndexes}\n $node={currentWidget}\n domRef={domRef}\n >\n {props.children}\n </Field>\n );\n\n // TODO: 需要不断移除 dataBinds(style/classList)\n function getBindData(forItems, scopeContext) {\n // bindData\n let wData = widgetsData;\n if (Array.isArray(wData)) {\n wData =\n forItems.forIndexes === void 0 || wData.length === 0\n ? {}\n : get(wData, getForIndexes(forItems, wData));\n }\n wData = wData || {};\n const fieldData = { ...wData };\n\n // 再次计算 scope value\n for (let key in fieldData) {\n if (Object.prototype.hasOwnProperty.call(fieldData, key)) {\n const value = fieldData[key];\n if (value && value.__type === 'scopedValue') {\n try {\n fieldData[key] = value.getValue(scopeContext);\n } catch (e) {\n console.warn(`Error computing data bind '${key}' error:`, e);\n fieldData[key] = '';\n }\n }\n }\n }\n\n // bindStyle\n let bindStyle = fieldData.style || {};\n // 复合组件第一层需要将最外层样式 style 挂到节点上\n let cssStyle = commonStyle;\n if (isInComposite && wData && !wData.parent) {\n cssStyle = {\n ...cssStyle,\n ...(codeContext.$WEAPPS_COMP.props?.style || {}),\n };\n bindStyle = {\n ...bindStyle,\n ...(codeContext.$WEAPPS_COMP.props?.style || {}),\n };\n }\n const finalStyle = getFinalStyle(cssStyle, bindStyle);\n\n // bindClassList\n const bindClassList = fieldData.classList || [];\n const finalClassNameList = getFinalClassNameList(\n classNameList,\n bindClassList\n );\n\n // 当前在复合组件中,且当前节点为根节点\n if (isInComposite && isRootNode) {\n if (wData.ownerWidget) {\n Object.keys(wData.ownerWidget).forEach((propName) => {\n if (\n propName === 'role' ||\n ['aria-', 'data-'].some((prefix) => propName.startsWith(prefix))\n ) {\n wData[propName] = wData.ownerWidget[propName];\n }\n });\n }\n }\n\n return { fieldData, finalStyle, finalClassNameList };\n }\n});\n\nexport function getFinalStyle(\n commonStyle = {},\n bindStyle = {},\n widgetStyle = {}\n) {\n const remBindStyle =\n typeof bindStyle === 'object' ? translateStyleToRem(bindStyle) : {};\n\n return {\n ...(translateStyleToRem(commonStyle) || {}),\n ...(translateStyleToRem(widgetStyle) || {}),\n ...remBindStyle,\n };\n}\n\nexport function getFinalClassNameList(\n classNameList = [],\n bindClassList = [],\n widgetClassList = []\n) {\n return [].concat(classNameList, bindClassList, widgetClassList);\n}\n\n// HACK: 从后向前保证循环的深度与 forIndexes 一致\n// 后续需要将 For 循环迁移到外层\nfunction getForIndexes(parentForItems, widgetsData) {\n return Array.isArray(widgetsData) && widgetsData.length > 0\n ? (parentForItems.forIndexes || []).slice(0 - getDeepArrLen(widgetsData))\n : undefined;\n}\n\nfunction getDeepArrLen(arr, len = 0) {\n if (Array.isArray(arr)) {\n return getDeepArrLen(arr[0], len + 1);\n } else {\n return len;\n }\n}\n\nfunction setGetDomApi(currentWidget, props) {\n if (!currentWidget) return React.createRef();\n const isComposite = !currentWidget.widgetType.startsWith('gsd-h5-react');\n const isInComposite = !!(props.codeContext || {}).$WEAPPS_COMP;\n\n // 如果当前是复合组件,不做 getDom 的挂载\n if (!isComposite) {\n if (!currentWidget.domRef) {\n currentWidget.domRef = React.createRef();\n }\n if (!currentWidget.getDom) {\n currentWidget.getDom = (options) =>\n getDom(currentWidget.domRef.current, options);\n }\n\n if (\n isInComposite && // 当前在复合组件内\n !currentWidget.parent && // 当前节点为复合组件的根节点\n props.codeContext.node && // 复合组件的 node 已经创建\n !props.codeContext.node.getDom // 复合组件的 node 未挂载 getDom 方法\n ) {\n props.codeContext.node.domRef = currentWidget.domRef;\n props.codeContext.node.getDom = currentWidget.getDom;\n }\n }\n\n return currentWidget.domRef;\n}\n"
26
+ "code": "import * as React from 'react';\nimport {\n useContext,\n useCallback,\n createContext,\n useState,\n useRef,\n} from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { emitEvent, translateStyleToRem, checkVisible } from '../utils';\nimport { get, set } from 'lodash';\nimport { getDom } from '../utils/widgets';\n\nexport const ForContext = createContext({});\n\nexport const CompRenderer = observer(function (props) {\n const {\n id: compId,\n xProps,\n virtualFields,\n slots = {},\n codeContext = {},\n scopeContext = {},\n genericComp = {},\n emitEvents = [],\n componentSchema = {},\n context = {},\n updateContext,\n } = props;\n\n const [blockIndex, setBlockIndex] = useState();\n const [blockType, setBlockType] = useState();\n const indexRef = useRef();\n const typeRef = useRef();\n indexRef.current = blockIndex;\n typeRef.current = blockType;\n\n const isInComposite = !!codeContext.$WEAPPS_COMP;\n // 判断 widgets 是从 page 来的,还是组件来的\n const widgetsData = !isInComposite\n ? codeContext.$page.widgets[compId]\n : codeContext.$WEAPPS_COMP.widgets[compId];\n\n const isRootNode = widgetsData && !widgetsData.parent;\n\n if (!xProps) {\n return props.children;\n }\n\n const {\n commonStyle = {},\n sourceKey,\n listenerInstances,\n classNameList = [],\n staticResourceAttribute = [],\n } = xProps;\n const dataBinds =\n (codeContext._dataBinds && codeContext._dataBinds[compId]) || {};\n const FieldKey = genericComp.propName\n ? codeContext.node[genericComp.propName]\n : sourceKey;\n const Field = virtualFields[FieldKey];\n const parentForItems = useContext(ForContext);\n\n // 组件最终用于执行的事件函数\n const emit = useCallback(\n (trigger, eventData, forItems, domEvent, scopeContext) => {\n // 如果是数据容器,则将传过来的data,赋值给容器上下文context\n if (\n trigger === 'onDataChange' &&\n componentSchema?.compConfig?.isDataContainer\n ) {\n updateContext(compId, eventData?.data);\n }\n\n const listeners = listenerInstances;\n const event = {\n detail: eventData,\n name: trigger,\n target: widgetsData,\n currentTarget: widgetsData,\n domEvent,\n };\n forItems = {\n ...forItems,\n forIndexes: getForIndexes(forItems, widgetsData),\n };\n emitEvent(\n trigger,\n listeners,\n {\n event,\n customEventData: event,\n forItems,\n domEvent,\n },\n scopeContext\n );\n },\n [props]\n );\n\n // 选区最终用于执行的事件函数\n const emitSB = useCallback(\n (trigger, eventData, forItems, domEvent, scopeContext, fieldData) => {\n const listeners =\n typeRef?.current &&\n indexRef?.current !== undefined &&\n fieldData?.[typeRef.current]?.[indexRef.current]?.selectableBlock?.[\n 'x-props'\n ]?.listenerInstances;\n const event = {\n detail: eventData,\n name: trigger,\n target: widgetsData,\n currentTarget: widgetsData,\n domEvent,\n };\n forItems = {\n ...forItems,\n forIndexes: getForIndexes(forItems, widgetsData),\n };\n emitEvent(\n trigger,\n listeners,\n {\n event,\n customEventData: event,\n forItems,\n domEvent,\n },\n scopeContext\n );\n },\n [props]\n );\n\n function getSafeComponentProps({\n style,\n classNameList,\n staticResourceAttribute,\n }) {\n const componentProps = {};\n if (classNameList.length) {\n componentProps.className = classNameList.join(' ');\n }\n\n if (style && Object.keys(style).length) {\n componentProps.style = style;\n }\n\n if (staticResourceAttribute && staticResourceAttribute.length > 0) {\n componentProps.staticResourceAttribute = staticResourceAttribute;\n }\n return componentProps;\n }\n\n // 选区的预览的click事件\n const onCustomEvent = ({ order: index, blockKey }) => {\n if (index !== undefined) {\n setBlockIndex(index);\n setBlockType(blockKey);\n }\n };\n\n // For循环渲染\n let forList;\n try {\n forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems, undefined, context);\n } catch (e) {\n forList = [];\n console.error('_waFor data', e);\n }\n if (forList) {\n if (!Array.isArray(forList)) {\n console.warn(`${compId}循环绑定非数组值:`, forList);\n forList = [];\n }\n return forList.map((item, index) => {\n const forItemsIndexes = (parentForItems.forIndexes || []).concat(index);\n const forItems = {\n ...parentForItems,\n [compId]: item,\n forIndexes: forItemsIndexes,\n };\n const {\n fieldData: forItemData,\n finalStyle: forItemStyle,\n finalClassNameList: forItemClassNameList,\n } = getBindData(forItems, scopeContext);\n if (!checkVisible(forItemData)) {\n return null;\n }\n // 多个组件的 slot 属性\n Object.keys(slots).forEach((slotProp) => {\n set(forItemData, slotProp, slots[slotProp]);\n });\n const emitWithForItems = (trigger, eventData, domEvent) =>\n emit(trigger, eventData, forItems, domEvent, scopeContext);\n\n const _selectableBlockEventsForItems = {\n onCustomEvent,\n events:\n componentSchema?.selectableBlock?.events.map((item) => item.name) ||\n [],\n emit: (trigger, eventData, domEvent) =>\n emitSB(\n trigger,\n eventData,\n forItems,\n domEvent,\n scopeContext,\n forItemData\n ),\n };\n\n delete forItemData.style;\n\n // 获取当前元素的 ref\n const currentWidget = Array.isArray(widgetsData)\n ? get(widgetsData, forItemsIndexes)\n : widgetsData;\n const domRef = setGetDomApi(currentWidget, props);\n\n // 判断为容器组件,则增加一个onDataChange事件\n if (\n componentSchema?.compConfig?.isDataContainer &&\n !emitEvents?.includes('onDataChange')\n ) {\n emitEvents.push('onDataChange');\n }\n\n return (\n <ForContext.Provider key={index} value={forItems}>\n <Field\n data={{\n ...forItemData,\n _selectableBlockEvents: _selectableBlockEventsForItems,\n }}\n id={compId}\n {...getSafeComponentProps({\n style: forItemStyle,\n classNameList: forItemClassNameList,\n staticResourceAttribute,\n })}\n emit={emitWithForItems}\n events={emitEvents}\n compositeParent={codeContext}\n forIndexes={forItemsIndexes}\n $node={currentWidget}\n domRef={domRef}\n >\n {props.children}\n </Field>\n </ForContext.Provider>\n );\n });\n }\n\n // 单节点渲染\n const { fieldData, finalClassNameList, finalStyle } = getBindData(\n parentForItems,\n scopeContext\n );\n const emitWithFiedle = (trigger, eventData, domEvent) =>\n emit(trigger, eventData, parentForItems, domEvent, scopeContext);\n\n const _selectableBlockEventsWithFiedle = {\n onCustomEvent,\n events:\n componentSchema?.selectableBlock?.events.map((item) => item.name) || [],\n emit: (trigger, eventData, domEvent) =>\n emitSB(\n trigger,\n eventData,\n parentForItems,\n domEvent,\n scopeContext,\n fieldData\n ),\n };\n\n // false 或空字符串时\n if (!checkVisible(fieldData)) {\n return null;\n }\n\n // 单个组件的 slot 属性\n Object.keys(slots).forEach((slotProp) => {\n set(fieldData, slotProp, slots[slotProp]);\n });\n\n // 防止渲染时 data 的 style 与实际的 style 冲突\n delete fieldData.style;\n\n // 修正 forIndexes\n const forIndexes = getForIndexes(parentForItems, widgetsData);\n\n // 获取 Element Ref\n const currentWidget = Array.isArray(widgetsData)\n ? get(widgetsData, forIndexes)\n : widgetsData;\n const domRef = setGetDomApi(currentWidget, props);\n\n // 判断为容器组件,则增加一个onDataChange事件\n if (\n componentSchema?.compConfig?.isDataContainer &&\n !emitEvents?.includes('onDataChange')\n ) {\n emitEvents.push('onDataChange');\n }\n\n return (\n <Field\n data={{\n ...fieldData,\n _selectableBlockEvents: _selectableBlockEventsWithFiedle,\n }}\n id={compId}\n {...getSafeComponentProps({\n style: finalStyle,\n classNameList: finalClassNameList,\n staticResourceAttribute,\n })}\n emit={emitWithFiedle}\n events={emitEvents}\n compositeParent={codeContext}\n forIndexes={forIndexes}\n $node={currentWidget}\n domRef={domRef}\n >\n {props.children}\n </Field>\n );\n\n // TODO: 需要不断移除 dataBinds(style/classList)\n function getBindData(forItems, scopeContext) {\n // bindData\n let wData = widgetsData;\n if (Array.isArray(wData)) {\n wData =\n forItems.forIndexes === void 0 || wData.length === 0\n ? {}\n : get(wData, getForIndexes(forItems, wData));\n }\n wData = wData || {};\n const fieldData = { ...wData };\n\n // 再次计算 scope value\n for (let key in fieldData) {\n if (Object.prototype.hasOwnProperty.call(fieldData, key)) {\n const value = fieldData[key];\n if (value && value.__type === 'scopedValue') {\n try {\n fieldData[key] = value.getValue(scopeContext);\n } catch (e) {\n console.warn(`Error computing data bind '${key}' error:`, e);\n fieldData[key] = '';\n }\n }\n }\n }\n\n // bindStyle\n let bindStyle = fieldData.style || {};\n // 复合组件第一层需要将最外层样式 style 挂到节点上\n let cssStyle = commonStyle;\n if (isInComposite && wData && !wData.parent) {\n cssStyle = {\n ...cssStyle,\n ...(codeContext.$WEAPPS_COMP.props?.style || {}),\n };\n bindStyle = {\n ...bindStyle,\n ...(codeContext.$WEAPPS_COMP.props?.style || {}),\n };\n }\n const finalStyle = getFinalStyle(cssStyle, bindStyle);\n\n // bindClassList\n const bindClassList = fieldData.classList || [];\n const finalClassNameList = getFinalClassNameList(\n classNameList,\n bindClassList\n );\n\n // 当前在复合组件中,且当前节点为根节点\n if (isInComposite && isRootNode) {\n if (wData.ownerWidget) {\n Object.keys(wData.ownerWidget).forEach((propName) => {\n if (\n propName === 'role' ||\n ['aria-', 'data-'].some((prefix) => propName.startsWith(prefix))\n ) {\n wData[propName] = wData.ownerWidget[propName];\n }\n });\n }\n }\n\n return { fieldData, finalStyle, finalClassNameList };\n }\n});\n\nexport function getFinalStyle(\n commonStyle = {},\n bindStyle = {},\n widgetStyle = {}\n) {\n const remBindStyle =\n typeof bindStyle === 'object' ? translateStyleToRem(bindStyle) : {};\n\n return {\n ...(translateStyleToRem(commonStyle) || {}),\n ...(translateStyleToRem(widgetStyle) || {}),\n ...remBindStyle,\n };\n}\n\nexport function getFinalClassNameList(\n classNameList = [],\n bindClassList = [],\n widgetClassList = []\n) {\n return [].concat(classNameList, bindClassList, widgetClassList);\n}\n\n// HACK: 从后向前保证循环的深度与 forIndexes 一致\n// 后续需要将 For 循环迁移到外层\nfunction getForIndexes(parentForItems, widgetsData) {\n return Array.isArray(widgetsData) && widgetsData.length > 0\n ? (parentForItems.forIndexes || []).slice(0 - getDeepArrLen(widgetsData))\n : undefined;\n}\n\nfunction getDeepArrLen(arr, len = 0) {\n if (Array.isArray(arr)) {\n return getDeepArrLen(arr[0], len + 1);\n } else {\n return len;\n }\n}\n\nfunction setGetDomApi(currentWidget, props) {\n if (!currentWidget) return React.createRef();\n const isComposite = !currentWidget.widgetType.startsWith('gsd-h5-react');\n const isInComposite = !!(props.codeContext || {}).$WEAPPS_COMP;\n\n // 如果当前是复合组件,不做 getDom 的挂载\n if (!isComposite) {\n if (!currentWidget.domRef) {\n currentWidget.domRef = React.createRef();\n }\n if (!currentWidget.getDom) {\n currentWidget.getDom = (options) =>\n getDom(currentWidget.domRef.current, options);\n }\n\n if (\n isInComposite && // 当前在复合组件内\n !currentWidget.parent && // 当前节点为复合组件的根节点\n props.codeContext.node && // 复合组件的 node 已经创建\n !props.codeContext.node.getDom // 复合组件的 node 未挂载 getDom 方法\n ) {\n props.codeContext.node.domRef = currentWidget.domRef;\n props.codeContext.node.getDom = currentWidget.getDom;\n }\n }\n\n return currentWidget.domRef;\n}\n"
27
27
  },
28
28
  "/src/handlers/RenderWrapper.jsx": {
29
- "code": "import * as React from 'react';\nimport { useRef } from 'react';\nimport { CompRenderer } from './NodeRenderer';\nimport lodashSet from 'lodash.set';\nimport cloneDeep from 'lodash.clonedeep';\nimport { isScopeSlot } from '../utils/common';\n\nfunction getComponentChildren(component) {\n const { properties } = component;\n if (!properties) {\n return [];\n }\n return Object.values(properties).sort(\n (a, b) => (a['x-index'] || 0) - (b['x-index'] || 0)\n );\n}\n\nexport function AppRender(props) {\n const {\n className,\n virtualFields,\n componentSchema,\n renderSlot,\n rootNode = true,\n codeContext,\n scopeContext = {},\n } = props;\n const {\n 'x-props': xProps,\n properties = {},\n genericComp = {},\n } = componentSchema;\n // 判断是否为 slot\n const isSlot = !xProps;\n if (isSlot && !(renderSlot || rootNode)) {\n return null;\n }\n\n const preClassName = useRef();\n\n // wrapperClass\n const containerEl = Object.values(properties)[0];\n if (containerEl && containerEl['x-props'] && className) {\n let { classNameList = [] } = containerEl['x-props'];\n\n // 先替换掉先前计算出来的className部分\n if (preClassName.current) {\n if (preClassName.current !== className) {\n classNameList = classNameList.filter(\n (clsName) => clsName !== preClassName.current\n );\n preClassName.current = className;\n }\n } else {\n preClassName.current = className;\n }\n\n containerEl['x-props'].classNameList = [className, ...classNameList];\n }\n\n if (xProps && xProps.sourceKey) {\n const { sourceKey } = xProps;\n const Field = virtualFields[sourceKey];\n if (!Field) {\n return (\n <div style={{ color: 'red' }}>\n 组件<em>{sourceKey}</em>未找到\n </div>\n );\n }\n }\n const children = getComponentChildren(componentSchema);\n const slots = {};\n // eslint-disable-next-line guard-for-in\n for (const key in properties) {\n const child = properties[key];\n if (!child['x-props'] && child.properties) {\n slots[key] = isScopeSlot(componentSchema, key) ? (\n (props) => {\n let clonedScopeContext = cloneDeep(scopeContext);\n lodashSet(\n clonedScopeContext,\n `${componentSchema.key}.${child.key}`,\n props\n );\n return (\n <AppRender\n key={child.key}\n componentSchema={child}\n renderSlot\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={clonedScopeContext}\n />\n );\n }\n ) : (\n <AppRender\n key={child.key}\n componentSchema={child}\n renderSlot\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={scopeContext}\n />\n );\n }\n }\n\n return (\n <CompRenderer\n id={componentSchema.key}\n xProps={xProps}\n emitEvents={componentSchema.emitEvents || []}\n componentSchema={componentSchema}\n virtualFields={virtualFields}\n slots={slots}\n codeContext={codeContext}\n scopeContext={scopeContext}\n genericComp={genericComp}\n >\n {children.map((comp) => (\n <AppRender\n key={comp.key}\n componentSchema={comp}\n rootNode={false}\n renderSlot={false}\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={scopeContext}\n />\n ))}\n </CompRenderer>\n );\n}\n"
29
+ "code": "import * as React from 'react';\nimport { useRef } from 'react';\nimport { CompRenderer } from './NodeRenderer';\nimport lodashSet from 'lodash.set';\nimport cloneDeep from 'lodash.clonedeep';\nimport { isScopeSlot } from '../utils/common';\n\nfunction getComponentChildren(component) {\n const { properties } = component;\n if (!properties) {\n return [];\n }\n return Object.values(properties).sort(\n (a, b) => (a['x-index'] || 0) - (b['x-index'] || 0)\n );\n}\n\nexport function AppRender(props) {\n const {\n className,\n virtualFields,\n componentSchema,\n renderSlot,\n rootNode = true,\n codeContext,\n scopeContext = {},\n context = {},\n updateContext,\n } = props;\n const {\n 'x-props': xProps,\n properties = {},\n genericComp = {},\n } = componentSchema;\n // 判断是否为 slot\n const isSlot = !xProps;\n if (isSlot && !(renderSlot || rootNode)) {\n return null;\n }\n\n const preClassName = useRef();\n\n // wrapperClass\n const containerEl = Object.values(properties)[0];\n if (containerEl && containerEl['x-props'] && className) {\n let { classNameList = [] } = containerEl['x-props'];\n\n // 先替换掉先前计算出来的className部分\n if (preClassName.current) {\n if (preClassName.current !== className) {\n classNameList = classNameList.filter(\n (clsName) => clsName !== preClassName.current\n );\n preClassName.current = className;\n }\n } else {\n preClassName.current = className;\n }\n\n containerEl['x-props'].classNameList = [className, ...classNameList];\n }\n\n if (xProps && xProps.sourceKey) {\n const { sourceKey } = xProps;\n const Field = virtualFields[sourceKey];\n if (!Field) {\n return (\n <div style={{ color: 'red' }}>\n 组件<em>{sourceKey}</em>未找到\n </div>\n );\n }\n }\n const children = getComponentChildren(componentSchema);\n const slots = {};\n // eslint-disable-next-line guard-for-in\n for (const key in properties) {\n const child = properties[key];\n if (!child['x-props'] && child.properties) {\n slots[key] = isScopeSlot(componentSchema, key) ? (\n (props) => {\n let clonedScopeContext = cloneDeep(scopeContext);\n lodashSet(\n clonedScopeContext,\n `${componentSchema.key}.${child.key}`,\n props\n );\n return (\n <AppRender\n key={child.key}\n componentSchema={child}\n renderSlot\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={clonedScopeContext}\n context={context}\n updateContext={updateContext}\n />\n );\n }\n ) : (\n <AppRender\n key={child.key}\n componentSchema={child}\n renderSlot\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={scopeContext}\n context={context}\n updateContext={updateContext}\n />\n );\n }\n }\n\n return (\n <CompRenderer\n id={componentSchema.key}\n xProps={xProps}\n emitEvents={componentSchema.emitEvents || []}\n componentSchema={componentSchema}\n virtualFields={virtualFields}\n slots={slots}\n codeContext={codeContext}\n scopeContext={scopeContext}\n genericComp={genericComp}\n context={context}\n updateContext={updateContext}\n >\n {children.map((comp) => (\n <AppRender\n key={comp.key}\n componentSchema={comp}\n rootNode={false}\n renderSlot={false}\n virtualFields={virtualFields}\n codeContext={codeContext}\n scopeContext={scopeContext}\n context={context}\n updateContext={updateContext}\n />\n ))}\n </CompRenderer>\n );\n}\n"
30
30
  },
31
31
  "/src/index.jsx": {
32
32
  "code": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport { setConfig } from '@cloudbase/weda-cloud-sdk/dist/h5'\nimport App from './router'\n<% if(!isSandbox){ %>\nimport './utils/monitor-jssdk.min'\n<% } %>\nimport './lowcode/style.css'\n// 引入数据源管理器并进行初始化\nimport './datasources'\nimport './utils/initGlobalVar'\n// import i18nData from './i18n/index.js'\nimport { initAppLifeCycle } from './utils/lifecycle'\n<% subAppDataList.forEach(subApp => { %>\n import './packages/<%= subApp.rootPath %>/lowcode/style.css'\n<% }) %>\n\n<% if(!isSandbox){ %>\nimport attachFastClick from 'fastclick'\nattachFastClick && attachFastClick.attach && attachFastClick.attach(document.body)\n<% } %>\nimport { app } from './app/global-api'\nimport { createStateDataSourceVar, generateParamsParser, EXTRA_API } from './datasources'\n\n\n// 初始化应用生命周期\ninitAppLifeCycle(app,{\n beforeCustomLaunch: (query)=>{\n EXTRA_API.setParams('$global', query || {})\n createStateDataSourceVar('$global',generateParamsParser({app}))\n }\n})\n\n<% if(!isSandbox && isBuildApp){ %>\n// app 中注册配置页面以及app的全局配置miniprogram.config,h5里分app以及web页分别处理,使用process.env.isApp 区分判断\nimport { initWebConfig } from './utils/lifecycle'\nimport AppConfig from '../webpack/miniprogram.config'\ninitWebConfig(app, AppConfig);\n<% } %>\n// 设置数据源请求的 loading 及 toast 处理\nsetConfig({\n beforeDSRequest: (cfg) => {\n if (!cfg.options || !cfg.options.showLoading) return\n app.showLoading()\n },\n afterDSRequest: (cfg, error, result) => {\n if (!cfg.options) return\n if (cfg.options.showLoading) app.hideLoading()\n if (!cfg.options.showToast) return\n const isSuccess = !error && result && !result.code\n app.showToast({icon: isSuccess ? 'success' : 'error'})\n }\n})\n\n\n<% if(!isSandbox){ %>\nif (yyptReport && typeof yyptReport.pgvMain == 'function') {\n // report_url,appKey必填\n yyptReport.pgvMain({\n appKey: '<%= yyptAppKey %>', // 填入你申请的运营平台的应用key(必填)\n report_url: '<%= reportUrl %><%= yyptAppKey %>', // 上报url(把后端上报接口需要先挂网关,该url填写网关地址)\n autoReportPv: true, // 单页应用监听页面路径改变自动上报Pv,默认为false\n stopReport: <%= stopReport %>, // 停止上报\n // 其他参数说明\n // customUserPrams: null, // 用户自定义的额外属性--对于小马的用户属性,比如用户的部门编码(customUserPrams: { deptno: 1100 })需要在小马系统事先配置好\n //userKey: \"user_id\", // cookie里面用户的唯一标示\n //autoWatchClick: true, // 默认开启自动监听hottag\n //isWxEnv: false// 是否微信环境,微信环境会通过wx.getNetworkType获取网络环境\n // 通过传入函数,可以让业务方写代码传入要上报的属性,比如返回自定义属性,这里主要也是自定义属性,让sdk获取并且进行上报,减少重复编码\n //getCusParams: function () {\n // return {kv:{money:1}}; //kv:Key-Value,自定义事件Key-Value参数对\tmap\tJSON格式,在报表页面的事件参数分析页和页面参数分析页中可以看到上报的kv值\n //},\n })\n}\n<% } %>\n\n;(function() {\n function flex() {\n try {\n let htmlDom = document.documentElement\n let width = window.innerWidth || htmlDom.clientWidth\n let fontSize = width / (375 / 14)\n if (\n !navigator.userAgent.match(\n /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i\n ) &&\n fontSize > 14\n ) {\n htmlDom.style.fontSize = `14px`\n } else {\n htmlDom.style.fontSize = fontSize + `px`\n }\n } catch (e) {\n console.error(e)\n }\n }\n\n flex()\n window.addEventListener('resize', flex)\n})()\nReactDOM.render(<App/>, document.getElementById('root'))\n\n<% if(!isSandbox){ %>\n// 使用HMR\nif(process.env.compileTool === 'vite') {\n if (import.meta.hot) {\n import.meta.hot.accept()\n }\n} else {\n if (process.env.NODE_ENV !== 'production') {\n if (module.hot) {\n module.hot.accept()\n }\n }\n}\n<% } %>\n"
@@ -35,7 +35,7 @@ exports.default = {
35
35
  "code": "// 针对小程序样式做适配\n// 请注意与weapps/src/pages/editor/components/Main/EditAndPreview/index.iframe.scss的一致性,以确保小程序端样式与\n\nbody {\n margin: 0;\n padding: 0;\n}\n\n#weapp-scancode-video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.weapp-scancode {\n &-close-button {\n background: white;\n color: black;\n display: flex;\n position: absolute;\n top: 14px;\n left: 14px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n cursor: pointer;\n justify-content: center;\n align-items: center;\n z-index: 500;\n }\n &-modal {\n position: fixed;\n background-color: black;\n left: 0px;\n right: 0px;\n top: 0px;\n bottom: 0px;\n &-main {\n height: 100%;\n position: relative;\n }\n }\n &-scan {\n &-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n top: 0;\n left: 0;\n }\n &-square {\n --square-size: 16rem;\n width: var(--square-size);\n height: var(--square-size);\n position: relative;\n }\n &-bar {\n position: absolute;\n height: 10px;\n width: 100%;\n background: linear-gradient(90deg, transparent, #07c160 50%, transparent);\n top: 0%;\n border-top-left-radius: 50%;\n border-top-right-radius: 50%;\n animation: slideinout-top-down 2s;\n animation-direction: normal;\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n }\n &-tip {\n margin-top: 10rem;\n color: white;\n }\n &-not-found {\n color: white;\n }\n &-not-found + p {\n color: #999;\n }\n }\n\n &-img-selector {\n position: absolute;\n bottom: 32px;\n right: 32px;\n z-index: 500;\n }\n &-img-picker {\n z-index: 500;\n padding: 5px;\n display: block;\n cursor: pointer;\n }\n}\n\n@keyframes slideinout-top-down {\n // use transform to prevent relayout\n 0% {\n transform: translateY(0px);\n opacity: 0;\n }\n 50% {\n transform: translateY(calc(var(--square-size) / 2));\n opacity: 0.5;\n }\n 100% {\n transform: translateY(var(--square-size));\n opacity: 0;\n }\n}\n\n@media (min-width: 1024px) {\n .weda-responsive_flex_flow {\n flex-flow: row !important;\n }\n}\n"
36
36
  },
37
37
  "/src/pages/app.tpl": {
38
- "code": "// Import Libs and Handlers\nimport * as React from 'react'\nimport { observable, autorun, reaction } from 'mobx'\nimport { observer } from \"mobx-react-lite\";\nimport get from 'lodash.get'\nimport { app } from '../../app/global-api' // 取对应子包app\nimport '../../utils/initGlobalVar'\nimport { AppRender } from '/src/handlers/RenderWrapper'\nimport { createDataset, createStateDataSourceVar, generateParamsParser, EXTRA_API } from '../../datasources'\nimport { createComputed, createWidgets, retryDataBinds, bindFuncObj, resolveComponentProps } from '/src/utils/index'\nimport { pageLifeCycleMount } from '/src/utils/lifecycle'\nimport { useScrollTop } from '/src/utils/hooks'\nimport PageLifeCycle from '../../lowcode/<%= pageName %>/lifecycle'\nimport initPageState from '../../lowcode/<%= pageName %>/state'\nimport computed from '../../lowcode/<%= pageName %>/computed'\nimport pageAPI from '../../lowcode/<%= pageName %>/index';\nimport { $$_<%= pageName %> as handler } from '../../app/handlers'\nimport { createPageApi } from '/src/app/global-api' // 取主包app\n\nimport '../../lowcode/<%= pageName %>/style.css'\n\n// Import Components\n<% useComponents.forEach(compItem => {%>\n<% if(isSandbox) { %>\nconst <%= upperFirst(compItem.variableName) %> = window[\"@weapps-materials-main-<%= compItem.materialName %>\"].components[\"<%= compItem.name %>\"];\n<% } else if(!isSandbox) { %>\nimport <%= upperFirst(compItem.variableName) %> from \"/src/libraries/<%= compItem.materialName %>@<%= compItem.materialVersion %>/components/<%= compItem.name %>\";\n<% }}) %>\n\n// Import Actions\n<% useActions.forEach(action => {%>\n<% if(isSandbox) { %>\nconst <%= action.variableName %> = window[\"@weapps-materials-main-<%= action.materialName %>\"].actions[\"<%= action.name %>\"];\n<% } else { %>\nimport <%= action.variableName %> from \"/src/libraries/<%= action.materialName %>@<%= action.materialVersion %>/actions/<%= action.name %>\";\n<% }}) %>\n\nconst virtualFields = {\n <% useComponents.forEach(compItem => {%>\n <% if(compItem.isPlainProps) { %>\n '<%= compItem.materialName %>:<%= compItem.name %>': (props) => <<%= upperFirst(compItem.variableName) %> {...resolveComponentProps(props, 1)} pageVirtualFields={virtualFields}/>,\n <% } else { %>\n '<%= compItem.materialName %>:<%= compItem.name %>': (props) => <<%= upperFirst(compItem.variableName) %> {...resolveComponentProps(props, 0)} pageVirtualFields={virtualFields}/>,\n <% }}) %>\n};\n\n// Init\nexport default function App() {\n // 检查权限\n // const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);\n\n // 兼容 this.state / $page.state 两种模式\n const pageCodeContext = createPageApi()\n const $page = pageCodeContext\n Object.defineProperty(pageCodeContext, '$page', {\n get() {\n return pageCodeContext\n }\n })\n\n const widgetsContext = <%= widgets %>;\n const dataBinds = $page._dataBinds = <%= dataBinds %>;\n const componentSchema = <%= componentSchema %>;\n\n Object.assign($page, {\n id:'<%= pageName %>',\n state: observable(initPageState),\n computed: createComputed(computed, pageCodeContext),\n handler: bindFuncObj(handler, pageCodeContext)\n })\n let dataset = createDataset('<%= pageName %>', {app, $page: pageCodeContext})\n $page.dataset = dataset\n $page.state.dataset = dataset\n $page.setState = (userSetState) => {\n Object.keys(userSetState).forEach((keyPath) => {\n app.utils.set($page.dataset.state, keyPath, userSetState[keyPath]);\n });\n };\n\n $page.widgets = createWidgets(widgetsContext, dataBinds)\n // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds\n retryDataBinds()\n\n // Web 环境页面级别生命周期\n React.useEffect(() => {\n document.title = \"<%= title %>\";\n initWatchMethods(pageCodeContext)\n /*checkAuth(app, app.id, '<%= pageName %>').then((checkAuthResult) =>\n setWeDaHasLogin(checkAuthResult)\n );*/\n }, [])\n\n pageLifeCycleMount(\n React.useEffect,\n {\n ...PageLifeCycle,\n beforePageCustomLaunch: (query) => {\n EXTRA_API.setParams('<%= pageName %>', query || {})\n createStateDataSourceVar('<%= pageName %>', generateParamsParser({ app, $page: pageCodeContext }))\n },\n },\n app,\n pageCodeContext\n )\n // 切换页面滚动到顶部\n useScrollTop()\n return (\n <div className=\"weapps-page weapps-page-<%= pageClass %>\">\n <style\n type=\"text/css\"\n dangerouslySetInnerHTML={{\n __html: `<%= pageStyleText %>`,\n }}\n />\n <AppRender\n virtualFields={virtualFields}\n componentSchema={componentSchema}\n codeContext={pageCodeContext}\n />\n </div>\n );\n\n function initWatchMethods(pageContext) {\n const { watch = {}, watchState = {}, watchWidget = {}, watchEffects = {}} = pageAPI\n\n\n // # watch effect\n const watchEffectDisposers = Object.keys(watchEffects).map(fnName => {\n return autorun(watchEffects[fnName].bind(pageContext))\n })\n const disposers = watchEffectDisposers\n\n // # watch state\n Object.keys(watchState).map(key => runWatcher(parseWatcher(watchState[key]), pageContext.state, key, 'watchState'))\n\n // # watch widgets\n Object.keys(watchWidget).map(key => runWatcher(parseWatcher(watchWidget[key]), pageContext.widgets, key, 'watchWidgets'))\n\n function runWatcher({ handler, immediate } = {}, target, key, label) {\n if (!handler) {\n console.error(`Invalid ${label}(${key}) of ${pageContext.node.widgetType}, watch must a function or {handler: function}`)\n return\n }\n const disposer = reaction(() => get(target, key), handler.bind(pageContext), { fireImmediately: immediate })\n disposers.push(disposer)\n }\n }\n}\n\nfunction parseWatcher(watcher) {\n if (!watcher) return\n if (watcher instanceof Function) {\n return { handler: watcher, immediate: false }\n }\n const { handler, immediate = false } = watcher\n if (!(handler instanceof Function)) return\n return { handler, immediate }\n}\n"
38
+ "code": "// Import Libs and Handlers\nimport * as React from 'react'\nimport { observable, autorun, reaction } from 'mobx'\nimport { observer } from \"mobx-react-lite\";\nimport get from 'lodash.get'\nimport { app } from '../../app/global-api' // 取对应子包app\nimport '../../utils/initGlobalVar'\nimport { AppRender } from '/src/handlers/RenderWrapper'\nimport { createDataset, createStateDataSourceVar, generateParamsParser, EXTRA_API } from '../../datasources'\nimport { createComputed, createWidgets, retryDataBinds, bindFuncObj, resolveComponentProps } from '/src/utils/index'\nimport { pageLifeCycleMount } from '/src/utils/lifecycle'\nimport { useScrollTop } from '/src/utils/hooks'\nimport PageLifeCycle from '../../lowcode/<%= pageName %>/lifecycle'\nimport initPageState from '../../lowcode/<%= pageName %>/state'\nimport computed from '../../lowcode/<%= pageName %>/computed'\nimport pageAPI from '../../lowcode/<%= pageName %>/index';\nimport { $$_<%= pageName %> as handler } from '../../app/handlers'\nimport { createPageApi } from '/src/app/global-api' // 取主包app\n\nimport '../../lowcode/<%= pageName %>/style.css'\n\n// Import Components\n<% useComponents.forEach(compItem => {%>\n<% if(isSandbox) { %>\nconst <%= upperFirst(compItem.variableName) %> = window[\"@weapps-materials-main-<%= compItem.materialName %>\"].components[\"<%= compItem.name %>\"];\n<% } else if(!isSandbox) { %>\nimport <%= upperFirst(compItem.variableName) %> from \"/src/libraries/<%= compItem.materialName %>@<%= compItem.materialVersion %>/components/<%= compItem.name %>\";\n<% }}) %>\n\n// Import Actions\n<% useActions.forEach(action => {%>\n<% if(isSandbox) { %>\nconst <%= action.variableName %> = window[\"@weapps-materials-main-<%= action.materialName %>\"].actions[\"<%= action.name %>\"];\n<% } else { %>\nimport <%= action.variableName %> from \"/src/libraries/<%= action.materialName %>@<%= action.materialVersion %>/actions/<%= action.name %>\";\n<% }}) %>\n\nconst virtualFields = {\n <% useComponents.forEach(compItem => {%>\n <% if(compItem.isPlainProps) { %>\n '<%= compItem.materialName %>:<%= compItem.name %>': (props) => <<%= upperFirst(compItem.variableName) %> {...resolveComponentProps(props, 1)} pageVirtualFields={virtualFields}/>,\n <% } else { %>\n '<%= compItem.materialName %>:<%= compItem.name %>': (props) => <<%= upperFirst(compItem.variableName) %> {...resolveComponentProps(props, 0)} pageVirtualFields={virtualFields}/>,\n <% }}) %>\n};\n\n// Init\nexport default function App() {\n // 检查权限\n // const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);\n const [context, setContext] = React.useState({});\n // 兼容 this.state / $page.state 两种模式\n const pageCodeContext = createPageApi()\n const $page = pageCodeContext\n Object.defineProperty(pageCodeContext, '$page', {\n get() {\n return pageCodeContext\n }\n })\n\n const widgetsContext = <%= widgets %>;\n const dataBinds = $page._dataBinds = <%= dataBinds %>;\n const componentSchema = <%= componentSchema %>;\n\n /**\n * 更新数据容器的上下文的方法\n * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文\n * 当组件卸载时,传过来的data为undefined即可\n * {\n * id1: [{...}],\n * id2: {...},\n * id3: undefined,\n * id4: null,\n * ...\n * }\n * @param id\n * @param data\n */\n const updateContext = (id, data) => {\n if(id) {\n context[id] = { data };\n }\n setContext({ ...context });\n }\n\n Object.assign($page, {\n id:'<%= pageName %>',\n state: observable(initPageState),\n computed: createComputed(computed, pageCodeContext),\n handler: bindFuncObj(handler, pageCodeContext)\n })\n let dataset = createDataset('<%= pageName %>', {app, $page: pageCodeContext})\n $page.dataset = dataset\n $page.state.dataset = dataset\n $page.setState = (userSetState) => {\n Object.keys(userSetState).forEach((keyPath) => {\n app.utils.set($page.dataset.state, keyPath, userSetState[keyPath]);\n });\n };\n\n $page.widgets = createWidgets(widgetsContext, dataBinds, context)\n // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds\n retryDataBinds()\n\n // Web 环境页面级别生命周期\n React.useEffect(() => {\n document.title = \"<%= title %>\";\n initWatchMethods(pageCodeContext)\n /*checkAuth(app, app.id, '<%= pageName %>').then((checkAuthResult) =>\n setWeDaHasLogin(checkAuthResult)\n );*/\n }, [])\n\n pageLifeCycleMount(\n React.useEffect,\n {\n ...PageLifeCycle,\n beforePageCustomLaunch: (query) => {\n EXTRA_API.setParams('<%= pageName %>', query || {})\n createStateDataSourceVar('<%= pageName %>', generateParamsParser({ app, $page: pageCodeContext }))\n },\n },\n app,\n pageCodeContext\n )\n // 切换页面滚动到顶部\n useScrollTop()\n return (\n <div className=\"weapps-page weapps-page-<%= pageClass %>\">\n <style\n type=\"text/css\"\n dangerouslySetInnerHTML={{\n __html: `<%= pageStyleText %>`,\n }}\n />\n <AppRender\n virtualFields={virtualFields}\n componentSchema={componentSchema}\n codeContext={pageCodeContext}\n context={context}\n updateContext={updateContext}\n />\n </div>\n );\n\n function initWatchMethods(pageContext) {\n const { watch = {}, watchState = {}, watchWidget = {}, watchEffects = {}} = pageAPI\n\n\n // # watch effect\n const watchEffectDisposers = Object.keys(watchEffects).map(fnName => {\n return autorun(watchEffects[fnName].bind(pageContext))\n })\n const disposers = watchEffectDisposers\n\n // # watch state\n Object.keys(watchState).map(key => runWatcher(parseWatcher(watchState[key]), pageContext.state, key, 'watchState'))\n\n // # watch widgets\n Object.keys(watchWidget).map(key => runWatcher(parseWatcher(watchWidget[key]), pageContext.widgets, key, 'watchWidgets'))\n\n function runWatcher({ handler, immediate } = {}, target, key, label) {\n if (!handler) {\n console.error(`Invalid ${label}(${key}) of ${pageContext.node.widgetType}, watch must a function or {handler: function}`)\n return\n }\n const disposer = reaction(() => get(target, key), handler.bind(pageContext), { fireImmediately: immediate })\n disposers.push(disposer)\n }\n }\n}\n\nfunction parseWatcher(watcher) {\n if (!watcher) return\n if (watcher instanceof Function) {\n return { handler: watcher, immediate: false }\n }\n const { handler, immediate = false } = watcher\n if (!(handler instanceof Function)) return\n return { handler, immediate }\n}\n"
39
39
  },
40
40
  "/src/pages/composite.tpl": {
41
41
  "code": "import * as React from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { observable, autorun, reaction, runInAction } from \"mobx\";\nimport { AppRender } from \"/src/handlers/RenderWrapper\";\nimport { createWidgets, retryDataBinds, WidgetsContext, bindFuncObj, createComputed, resolveComponentProps} from '/src/utils/index'\nimport getStateFn from \"./lowcode/state.js\";\nimport computed from \"./lowcode/computed.js\";\nimport lifecycle from \"./lowcode/lifecycle.js\";\n// import i18n from '@tcwd/weapps-sdk/lib/i18n'\n<% if(isSandbox) { %>\nimport { ErrorBoundary } from 'react-error-boundary'\nimport { createErrorFallback } from '/src/utils/error'\n<% } %>\nimport componentAPI from './lowcode/index';\nimport get from 'lodash.get'\n\n<% handlersImports.forEach(handler => { %>\nimport handler$<%= handler.name %> from \"./lowcode/handler/<%= handler.name %>.js\";\n<% }) %>\n\n// Import Components outof sandbox\n<% useComponents.forEach(compItem => {%>\n<% if(!isSandbox && compItem.isComposite){ %>\nimport <%= compItem.var %> from \"/src/libraries/<%= compItem.moduleName %>@<%= compItem.version %>/components/<%= compItem.name %>\";\n<% } else if(!isSandbox) { %>\nconst <%= compItem.var %> = window[\"@weapps-materials-main-<%= compItem.moduleName %>\"].components[\"<%= compItem.name %>\"];\n<% } %>\n<%}) %>\n\nimport * as constObj from '../../libCommonRes/const'\nimport * as toolsObj from '../../libCommonRes/tools'\n\nimport \"./lowcode/style.css\";\n\nconst libCode = '<%= materialName %>'\n\nclass CompositeCompWrapper extends React.Component {\n\n $WEAPPS_COMP = {}\n\n componentDidUpdate() {\n runInAction(() => {\n const { data } = this.props\n for(let prop in data) {\n // 更新 propsData\n if (typeof data[prop] !== 'function') {\n this.propsData[prop] = data[prop]\n }\n }\n })\n }\n\n\n constructor(props) {\n super(props);\n\n this.compConfig = <%= JSON.stringify(compConfig, null, 2) %>\n\n // Import Components in sandbox\n <% useComponents.forEach(compItem => {%>\n <% if(isSandbox){ %>\n const <%= compItem.var %> = window[\"@weapps-materials-main-<%= compItem.moduleName %>\"].components[\"<%= compItem.name %>\"];\n <% } %>\n <%}) %>\n\n this.virtualFields = Object.assign({}, props.pageVirtualFields || {}, {\n <% useComponents.forEach(compItem => {%>\n \"<%= compItem.key %>\": <% if(compItem.isPlainProps) {%> (props) => <<%= compItem.var %> {...resolveComponentProps(props, 1)} /> <% } else {%> (props) => <<%= compItem.var %>{...resolveComponentProps(props, 0)} /> <% }%>,\n <%}) %>\n });\n\n // 挂载给到 $comp.props.events 使用\n this.events = (<%= emitEvents %>).reduce((obj, trigger) => {\n obj[trigger] = (eventData, domEvent) => {\n this.props.emit(trigger, eventData, domEvent);\n this.node._listeners && this.node._listeners.emit(trigger, eventData, domEvent)\n };\n return obj;\n }, {});\n this.handler = this.$WEAPPS_COMP.handler = {\n <% handlersImports.forEach(handler => { %>\n <%= handler.name %>: handler$<%= handler.name %>.bind(this),\n <% }) %>\n };\n const widgetContext = <%= widgets %>\n const dataBinds = this._dataBinds = <%= dataBinds %>\n this.componentSchema = <%= componentSchema %>;\n\n const defaultProps = <%= JSON.stringify(defaultProps, null, 2) %>\n this.propsData = observable(Object.assign({}, defaultProps, this.props.data || {}))\n this.$WEAPPS_COMP.lib = { const: constObj, tools: toolsObj }\n /*\n this.i18n = this.$WEAPPS_COMP.i18n = {\n ...i18n,\n t (key, data) {\n return i18n.t(libCode + ':' + key, data)\n },\n }\n */\n this.$WEAPPS_COMP.props = { ...this.props, events: this.events, data: this.propsData }\n\n this.state = this.$WEAPPS_COMP.state = observable(getStateFn.bind(this)())\n this.computed = this.$WEAPPS_COMP.computed = createComputed(computed, this)\n this.node = this.$WEAPPS_COMP.node = this.createWidgetNode(this) || {}\n this.initPublicMethods()\n\n this.widgets = this.$WEAPPS_COMP.widgets = createWidgets(widgetContext, dataBinds)\n // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds\n retryDataBinds()\n Object.keys(this.widgets || {}).forEach(widgetId => {\n // 将实例 ownerWidget 挂到内部组件上。内部组件就可以通过 $comp.node.ownerWidget 获取到所在的组件实例\n const node = this.widgets[widgetId]\n if (Array.isArray(node)) {\n node.forEach(item => {\n item.ownerWidget = this.node;\n item.getOwnerWidget = () => this.node;\n })\n }\n else {\n node.ownerWidget = this.node\n node.getOwnerWidget = () => this.node\n }\n // this.widgets[widgetId].ownerWidget = this.node\n // this.widgets[widgetId].getOwnerWidget = () => this.node\n })\n\n this.pageListenerInstances = [];\n this.createCompAPI(this)\n }\n\n // publicMthods 挂载内部,使用 $comp.api。挂载到外部使用 $comp.node.api\n initPublicMethods() {\n const publicMethods = componentAPI.publicMethods || {}\n Object.keys(publicMethods).map(fnName => {\n const bindFunc = publicMethods[fnName].bind(this)\n this[fnName] = bindFunc\n this.$WEAPPS_COMP[fnName] = bindFunc\n if(this.node) this.node[fnName] = bindFunc\n })\n }\n\n // 创建自身节点\n createWidgetNode(compThis) {\n // 当为数组时,需要判断自己属于 widgets 的哪一项\n const {\n compositeParent,\n forIndexes,\n id\n } = compThis.props\n let widgetData = compositeParent.$WEAPPS_COMP\n ? compositeParent.$WEAPPS_COMP.widgets[id]\n : compositeParent.$page.widgets[id]\n if(Array.isArray(widgetData)) {\n widgetData = widgetData.length > 0 ? get(widgetData, forIndexes) : {}\n }\n widgetData = widgetData || {}\n Object.assign(widgetData, {\n getConfig: () => compThis.compConfig,\n }, bindFuncObj(componentAPI.publicMethods || {}, compThis)\n )\n\n return widgetData\n }\n\n createCompAPI(compThis) {\n compThis.$WEAPPS_COMP = {\n _dataBinds: compThis._dataBinds,\n compConfig: compThis.compConfig,\n widgets: compThis.widgets,\n node: compThis.node,\n handler: compThis.handler,\n lib: { const: constObj, tools: toolsObj },\n // i18n: compThis.i18n,\n get props() {\n return {...compThis.props, events: compThis.events, data: compThis.propsData }\n },\n get state() {\n return compThis.state\n },\n get computed() {\n return compThis.computed\n },\n };\n }\n\n initWatchMethods() {\n const { watch = {}, watchState = {}, watchWidget = {}, watchEffects = {}} = componentAPI\n const _this = this\n const weappInst = _this.$WEAPPS_COMP\n\n // # watch effect\n this.watchEffectDisposers = Object.keys(watchEffects).map(fnName => {\n return autorun(watchEffects[fnName].bind(this))\n })\n const disposers = this.watchEffectDisposers\n\n // # watch props\n Object.keys(watch).map(key => runWatcher(parseWatcher(watch[key]), weappInst.props.data, key, 'watch'))\n\n // # watch state\n Object.keys(watchState).map(key => runWatcher(parseWatcher(watchState[key]), weappInst.state, key, 'watchState'))\n\n // # watch widgets\n Object.keys(watchWidget).map(key => runWatcher(parseWatcher(watchWidget[key]), weappInst.widgets, key, 'watchWidgets'))\n\n function runWatcher({ handler, immediate } = {}, target, key, label) {\n if (!handler) {\n console.error(`Invalid ${label}(${key}) of ${weappInst.node.widgetType}, watch must a function or {handler: function}`)\n return\n }\n const disposer = reaction(() => get(target, key), handler.bind(_this), { fireImmediately: immediate })\n disposers.push(disposer)\n }\n }\n\n componentDidMount() {\n this.initPublicMethods()\n this.initWatchMethods()\n\n lifecycle.onAttached && lifecycle.onAttached.bind(this)()\n lifecycle.onReady && lifecycle.onReady.bind(this)()\n }\n\n componentWillUnmount() {\n if(this.watchEffectDisposers) {\n this.watchEffectDisposers.forEach(disposer => disposer())\n this.watchEffectDisposers = null\n }\n this.node._listeners && this.node._listeners.clear()\n lifecycle.onDetached && lifecycle.onDetached.bind(this)()\n }\n\n render() {\n return (\n <WidgetsContext.Provider value={{ parent: this }}>\n <AppRender\n className={this.props.className}\n virtualFields={this.virtualFields}\n componentSchema={this.componentSchema}\n codeContext={this}\n />\n </WidgetsContext.Provider>\n );\n }\n}\n\nCompositeCompWrapper.contextType = WidgetsContext\n\nexport default observer((props) => (\n <% if(isSandbox) { %>\n <ErrorBoundary FallbackComponent={createErrorFallback('<%= name %>', '<%= id %>')}>\n <% } %>\n <CompositeCompWrapper {...props}></CompositeCompWrapper>\n <% if(isSandbox) { %>\n </ErrorBoundary>\n <% } %>\n));\n\nfunction parseWatcher(watcher) {\n if (!watcher) return\n if (watcher instanceof Function) {\n return { handler: watcher, immediate: false }\n }\n const { handler, immediate = false } = watcher\n if (!(handler instanceof Function)) return\n return { handler, immediate }\n}\n"
@@ -98,6 +98,6 @@ exports.default = {
98
98
  "code": "import { kebabCase, camelcase, isEmptyObj } from './common';\n\nconst PERCENTAGE_KEY_LIST = [\n 'opacity',\n 'order',\n 'flex',\n 'flexGrow',\n 'flexShrink',\n 'zIndex',\n 'fontWeight',\n 'borderImage',\n];\n\nexport function translateStyleToRem(style) {\n return translateStyleByHandler(style, toREM);\n}\n\nexport function translateStyleByHandler(style, handler) {\n return Object.keys(style).reduce((result, key) => {\n const value = style[key];\n if (PERCENTAGE_KEY_LIST.includes(key)) {\n setStyleValue(result, key, value);\n } else if (value !== undefined && value !== null) {\n setStyleValue(result, key, handler(value));\n }\n return result;\n }, {});\n}\n\nfunction setStyleValue(object, key, value) {\n if (value === undefined || value === null || value === '') {\n return;\n }\n // 特殊样式移除\n if (key === 'open') {\n return;\n }\n\n if (isEmptyObj(value)) {\n return;\n }\n\n object[camelcase(key)] = value;\n}\n\nfunction calPxToREM(px) {\n if (Number.isNaN(px / 28)) return px.toString();\n if (+px === 0) {\n return '0';\n }\n return (px / 28).toFixed(4) + 'rem';\n}\n\nexport function toREM(cssLen) {\n if (typeof cssLen === 'string') {\n const cssLenArr = cssLen.split(' ');\n return cssLenArr\n .map((attr) => {\n const matchResult = attr.match(/^(-?\\d+)(px)?$/);\n if (matchResult && matchResult[1]) {\n return calPxToREM(+matchResult[1]);\n }\n return attr;\n })\n .join(' ');\n }\n\n if (typeof cssLen === 'number') {\n return calPxToREM(cssLen);\n }\n}\n\nexport function toCssText(style, className = '.some-class-name') {\n const attrText = Object.keys(style)\n .map((key) => {\n const value = style[key];\n return `${kebabCase(key)}: ${value};`;\n })\n .join('\\n');\n return `${className} { ${attrText} }\\n`;\n}\n"
99
99
  },
100
100
  "/src/utils/widgets.js": {
101
- "code": "import * as React from 'react';\nimport { observable, autorun, untracked } from 'mobx';\nimport remove from 'lodash.remove';\nimport { EventProxy } from './eventProxy';\n\nexport const widgetKeys = [\n 'getConfig',\n 'findWidgets',\n 'getWidgetsByType',\n 'extends',\n 'on',\n 'off',\n 'getOwnerWidget',\n 'getDom',\n 'domRef',\n];\n\nexport const WidgetsContext = React.createContext({ parent: null });\n\nexport function isSlot(comp) {\n return !comp['x-props'];\n}\n\nexport function checkVisible({ _visible }) {\n return _visible !== false && _visible !== '';\n}\n\n// 实现和小程序一致的 API,以兼容多端\n// widget.getDom({ rect: true })\n// https://developers.weixin.qq.com/miniprogram/dev/api/wxml/NodesRef.fields.html\nexport function getDom(element, options) {\n if (!element) {\n console.warn('getDom 接口未传入有效的 element');\n return Promise.resolve({});\n }\n\n let result = {};\n if (options.id) result.id = element.id;\n if (options.dataset) result.dataset = element.dataset;\n if (options.rect) {\n const rect = element.getBoundingClientRect();\n Object.assign(result, {\n left: rect.left,\n right: rect.right,\n top: rect.top,\n bottom: rect.bottom,\n });\n }\n if (options.size) {\n const rect = element.getBoundingClientRect();\n Object.assign(result, {\n width: rect.width,\n height: rect.height,\n });\n }\n if (options.scrollOffset) {\n Object.assign(result, {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop,\n });\n }\n if (options.properties && Array.isArray(options.properties)) {\n options.properties.forEach((propName) => {\n result[propName] = element.getAttribute(propName);\n });\n }\n if (options.computedStyle && Array.isArray(options.computedStyle)) {\n const computedStyle = window.getComputedStyle(element);\n options.computedStyle.forEach((propName) => {\n result[propName] = computedStyle[propName];\n });\n }\n\n return Promise.resolve(result);\n}\n\nexport function findWidgets(\n widget,\n parentType,\n filterFn,\n includeInvisibleDescendants\n) {\n if (!widget) return [];\n\n let { children = [] } = widget;\n let matched = children.filter(filterFn);\n\n // 过滤掉不可见后代\n if (!includeInvisibleDescendants) {\n children = children.filter((item) => checkVisible(item));\n }\n\n children.forEach((child) => {\n // 如果递归过程中发现了自己,则停止递归\n matched = matched.concat(\n findWidgets(child, parentType, filterFn, includeInvisibleDescendants)\n );\n });\n\n // 过滤掉不可见的匹配项\n if (!includeInvisibleDescendants) {\n matched = matched.filter((item) => checkVisible(item));\n }\n\n return matched;\n}\n\nconst retryQueue = [];\n// 递归执行\nexport function retryDataBinds(tryTime = 10) {\n const fn = retryQueue.shift();\n if (!fn || tryTime <= 0) return;\n try {\n fn({ showLog: tryTime <= 1 });\n } catch (e) {\n console.error('retryDataBinds', e);\n }\n retryDataBinds(tryTime - 1);\n}\nexport function createWidgets(widgetProps, dataBinds) {\n const nodeTree = createWidgetTree(widgetProps, dataBinds);\n const widgets = runFor(nodeTree, {}, null, null);\n return widgets;\n\n /**\n *\n * @param {*} curForNode\n * @param {*} forItems\n * @param {*} parentLevelWidgets\n * @param {*} parentWidget\n * @returns top level widgets or for dispose\n */\n function runFor(curForNode, forItems, parentLevelWidgets, parentWidget) {\n const nodeId = curForNode.id;\n if (!curForNode.value) {\n return createSubTree(curForNode, {});\n }\n const dispose = autorun(() => {\n let forList = [];\n try {\n forList = dataBinds[nodeId]._waFor(forItems);\n } catch (e) {\n console.error('waFor error', e);\n }\n\n if (!Array.isArray(forList)) {\n console.warn(nodeId, 'For 循环绑定的数据并不是数组,请检查');\n return;\n }\n\n // 让 forList 进行监听\n forList.forEach(() => {});\n untracked(() => {\n disposeWidgets(parentLevelWidgets[curForNode.id]);\n\n // clean nodes of previouse for run\n dfsTree(curForNode, (node) => {\n const arr = parentLevelWidgets[node.id];\n arr.splice(0, arr.length);\n parentWidget &&\n remove(parentWidget.children, ({ id }) => id === node.id);\n });\n\n forList.forEach((item, index) => {\n const subForItems = { ...forItems, [nodeId]: item };\n createSubTree(curForNode, subForItems);\n });\n\n // 非初始化时遇到需要重新构建 dataBinds\n retryDataBinds();\n });\n });\n\n return dispose;\n\n function createSubTree(curForNode, subForItems) {\n const widgets = {};\n\n // traverse down the tree to set all widgets\n dfsTree(curForNode, (node, parentNode) => {\n if (node.forCount === curForNode.forCount) {\n // Leaf node\n const w = observable(widgetProps[node.id]);\n w.id = node.id;\n if (node === curForNode) {\n w._disposers = [];\n }\n widgets[node.id] = w;\n w._listeners = new EventProxy();\n // 提供一个给 Node 挂载 API 的方式\n untracked(() => {\n w.getConfig = () => ({}); // 兼容非复合组件调用 getConfig 能力\n w.findWidgets = (type, includeInvisibleDescendants) =>\n findWidgets(w, w.widgetType, type, includeInvisibleDescendants);\n w.getWidgetsByType = (type, includeInvisibleDescendants) =>\n w.findWidgets(\n (currentWidget) => currentWidget.widgetType === type,\n includeInvisibleDescendants\n );\n w.extends = (name, fnOrData) =>\n Object.defineProperty(w, name, {\n value: fnOrData,\n writable: true,\n });\n w.on = (name, listener) => w._listeners.on(name, listener);\n w.off = (name, listener) => w._listeners.cancel(name, listener);\n w.getOwnerWidget = () => null; // 默认带上一个 widget\n });\n w.children = [];\n const parent = parentNode ? widgets[parentNode.id] : parentWidget;\n if (parent) {\n w.parent = parent;\n // 只有可显示 visible 的才存入 children 里\n if (checkVisible(w)) {\n parent.children.push(w);\n }\n }\n parentLevelWidgets && parentLevelWidgets[node.id].push(w);\n\n // Setup data binds\n Object.keys(dataBinds[node.id] || {}).map((prop) => {\n if (prop === '_waFor') {\n return;\n }\n function getBindData(options = {}) {\n let disposeError = false;\n const dispose = autorun(() => {\n try {\n // Computed data bind in the next tick since data bind may read widgets data\n w[prop] = dataBinds[node.id][prop](subForItems);\n disposeError = false;\n } catch (e) {\n console.warn(`Error computing data bind ${w.id}.${prop}`, e);\n if (prop === '_waIf') {\n w[prop] = false;\n } else {\n options.showLog && console.warn(e);\n retryQueue.push(getBindData);\n disposeError = true;\n }\n }\n });\n if (!disposeError && curForNode.id) {\n widgets[curForNode.id]._disposers.push(dispose);\n }\n }\n getBindData();\n });\n } else {\n if (parentLevelWidgets) {\n const len = parentLevelWidgets[node.id].push([]);\n widgets[node.id] = parentLevelWidgets[node.id][len - 1];\n } else {\n widgets[node.id] = observable([]);\n }\n }\n });\n\n // run for of next level\n dfsTree(curForNode, (node, parentNode) => {\n if (\n node.forCount === curForNode.forCount + 1 &&\n dataBinds[node.id] &&\n dataBinds[node.id]._waFor\n ) {\n widgets[node.id]._disposers = { dataBinds: [] };\n const dispose = runFor(\n node,\n subForItems,\n widgets,\n node.parent && widgets[node.parent.id]\n );\n curForNode.id && widgets[curForNode.id]._disposers.push(dispose);\n }\n });\n\n return widgets;\n }\n }\n}\n\n/**\n * Add parent, children to widget\n */\nfunction createWidgetTree(widgets, dataBinds) {\n const virtualRoot = { children: [], forCount: 0 };\n const nodes = Object.keys(widgets).reduce((result, id) => {\n result[id] = {\n id,\n value: widgets[id],\n children: [],\n parent: null,\n forCount: 0,\n };\n return result;\n }, {});\n\n // Create widgets tree API\n Object.keys(nodes).map((id) => {\n const curNode = nodes[id];\n const parent = nodes[widgets[id]._parentId];\n if (!parent) {\n virtualRoot.children.push(curNode);\n return;\n }\n curNode.parent = parent;\n parent.children.push(curNode);\n });\n\n virtualRoot.children.map(addForCount);\n\n // dfs, add forCount\n function addForCount(node) {\n if (node.parent) {\n node.forCount = node.parent.forCount;\n }\n if (dataBinds[node.id] && dataBinds[node.id]._waFor) {\n node.forCount++;\n }\n node.children.map(addForCount);\n }\n\n return virtualRoot;\n}\n\nfunction dfsTree(node, fn, parent) {\n node.value && fn(node, parent);\n node.children.map((e) => dfsTree(e, fn, node.value ? node : null));\n}\n\n// dispose autorun\nfunction disposeWidgets(widgets = []) {\n widgets.forEach((widget) => {\n const disposers = widget._disposers;\n if (disposers) {\n disposers.map((dispose) => dispose());\n disposers.splice(0, disposers.length);\n }\n disposeWidgets(widget.children);\n });\n}\n"
101
+ "code": "import * as React from 'react';\nimport { observable, autorun, untracked } from 'mobx';\nimport remove from 'lodash.remove';\nimport { EventProxy } from './eventProxy';\n\nexport const widgetKeys = [\n 'getConfig',\n 'findWidgets',\n 'getWidgetsByType',\n 'extends',\n 'on',\n 'off',\n 'getOwnerWidget',\n 'getDom',\n 'domRef',\n];\n\nexport const WidgetsContext = React.createContext({ parent: null });\n\nexport function isSlot(comp) {\n return !comp['x-props'];\n}\n\nexport function checkVisible({ _visible }) {\n return _visible !== false && _visible !== '';\n}\n\n// 实现和小程序一致的 API,以兼容多端\n// widget.getDom({ rect: true })\n// https://developers.weixin.qq.com/miniprogram/dev/api/wxml/NodesRef.fields.html\nexport function getDom(element, options) {\n if (!element) {\n console.warn('getDom 接口未传入有效的 element');\n return Promise.resolve({});\n }\n\n let result = {};\n if (options.id) result.id = element.id;\n if (options.dataset) result.dataset = element.dataset;\n if (options.rect) {\n const rect = element.getBoundingClientRect();\n Object.assign(result, {\n left: rect.left,\n right: rect.right,\n top: rect.top,\n bottom: rect.bottom,\n });\n }\n if (options.size) {\n const rect = element.getBoundingClientRect();\n Object.assign(result, {\n width: rect.width,\n height: rect.height,\n });\n }\n if (options.scrollOffset) {\n Object.assign(result, {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop,\n });\n }\n if (options.properties && Array.isArray(options.properties)) {\n options.properties.forEach((propName) => {\n result[propName] = element.getAttribute(propName);\n });\n }\n if (options.computedStyle && Array.isArray(options.computedStyle)) {\n const computedStyle = window.getComputedStyle(element);\n options.computedStyle.forEach((propName) => {\n result[propName] = computedStyle[propName];\n });\n }\n\n return Promise.resolve(result);\n}\n\nexport function findWidgets(\n widget,\n parentType,\n filterFn,\n includeInvisibleDescendants\n) {\n if (!widget) return [];\n\n let { children = [] } = widget;\n let matched = children.filter(filterFn);\n\n // 过滤掉不可见后代\n if (!includeInvisibleDescendants) {\n children = children.filter((item) => checkVisible(item));\n }\n\n children.forEach((child) => {\n // 如果递归过程中发现了自己,则停止递归\n matched = matched.concat(\n findWidgets(child, parentType, filterFn, includeInvisibleDescendants)\n );\n });\n\n // 过滤掉不可见的匹配项\n if (!includeInvisibleDescendants) {\n matched = matched.filter((item) => checkVisible(item));\n }\n\n return matched;\n}\n\nconst retryQueue = [];\n// 递归执行\nexport function retryDataBinds(tryTime = 10) {\n const fn = retryQueue.shift();\n if (!fn || tryTime <= 0) return;\n try {\n fn({ showLog: tryTime <= 1 });\n } catch (e) {\n console.error('retryDataBinds', e);\n }\n retryDataBinds(tryTime - 1);\n}\nexport function createWidgets(widgetProps, dataBinds, context) {\n const nodeTree = createWidgetTree(widgetProps, dataBinds);\n const widgets = runFor(nodeTree, {}, null, null, context);\n return widgets;\n\n /**\n *\n * @param {*} curForNode\n * @param {*} forItems\n * @param {*} parentLevelWidgets\n * @param {*} parentWidget\n * @param {*} context\n * @returns top level widgets or for dispose\n */\n function runFor(curForNode, forItems, parentLevelWidgets, parentWidget, context) {\n const nodeId = curForNode.id;\n if (!curForNode.value) {\n return createSubTree(curForNode, {});\n }\n const dispose = autorun(() => {\n let forList = [];\n try {\n forList = dataBinds[nodeId]._waFor(forItems, undefined, context);\n } catch (e) {\n console.error('waFor error', e);\n }\n\n if (!Array.isArray(forList)) {\n console.warn(nodeId, 'For 循环绑定的数据并不是数组,请检查');\n return;\n }\n\n // 让 forList 进行监听\n forList.forEach(() => {});\n untracked(() => {\n disposeWidgets(parentLevelWidgets[curForNode.id]);\n\n // clean nodes of previouse for run\n dfsTree(curForNode, (node) => {\n const arr = parentLevelWidgets[node.id];\n arr.splice(0, arr.length);\n parentWidget &&\n remove(parentWidget.children, ({ id }) => id === node.id);\n });\n\n forList.forEach((item, index) => {\n const subForItems = { ...forItems, [nodeId]: item };\n createSubTree(curForNode, subForItems);\n });\n\n // 非初始化时遇到需要重新构建 dataBinds\n retryDataBinds();\n });\n });\n\n return dispose;\n\n function createSubTree(curForNode, subForItems) {\n const widgets = {};\n\n // traverse down the tree to set all widgets\n dfsTree(curForNode, (node, parentNode) => {\n if (node.forCount === curForNode.forCount) {\n // Leaf node\n const w = observable(widgetProps[node.id]);\n w.id = node.id;\n if (node === curForNode) {\n w._disposers = [];\n }\n widgets[node.id] = w;\n w._listeners = new EventProxy();\n // 提供一个给 Node 挂载 API 的方式\n untracked(() => {\n w.getConfig = () => ({}); // 兼容非复合组件调用 getConfig 能力\n w.findWidgets = (type, includeInvisibleDescendants) =>\n findWidgets(w, w.widgetType, type, includeInvisibleDescendants);\n w.getWidgetsByType = (type, includeInvisibleDescendants) =>\n w.findWidgets(\n (currentWidget) => currentWidget.widgetType === type,\n includeInvisibleDescendants\n );\n w.extends = (name, fnOrData) =>\n Object.defineProperty(w, name, {\n value: fnOrData,\n writable: true,\n });\n w.on = (name, listener) => w._listeners.on(name, listener);\n w.off = (name, listener) => w._listeners.cancel(name, listener);\n w.getOwnerWidget = () => null; // 默认带上一个 widget\n });\n w.children = [];\n const parent = parentNode ? widgets[parentNode.id] : parentWidget;\n if (parent) {\n w.parent = parent;\n // 只有可显示 visible 的才存入 children 里\n if (checkVisible(w)) {\n parent.children.push(w);\n }\n }\n parentLevelWidgets && parentLevelWidgets[node.id].push(w);\n\n // Setup data binds\n Object.keys(dataBinds[node.id] || {}).map((prop) => {\n if (prop === '_waFor') {\n return;\n }\n function getBindData(options = {}) {\n let disposeError = false;\n const dispose = autorun(() => {\n try {\n // Computed data bind in the next tick since data bind may read widgets data\n w[prop] = dataBinds[node.id][prop](subForItems);\n disposeError = false;\n } catch (e) {\n console.warn(`Error computing data bind ${w.id}.${prop}`, e);\n if (prop === '_waIf') {\n w[prop] = false;\n } else {\n options.showLog && console.warn(e);\n retryQueue.push(getBindData);\n disposeError = true;\n }\n }\n });\n if (!disposeError && curForNode.id) {\n widgets[curForNode.id]._disposers.push(dispose);\n }\n }\n getBindData();\n });\n } else {\n if (parentLevelWidgets) {\n const len = parentLevelWidgets[node.id].push([]);\n widgets[node.id] = parentLevelWidgets[node.id][len - 1];\n } else {\n widgets[node.id] = observable([]);\n }\n }\n });\n\n // run for of next level\n dfsTree(curForNode, (node, parentNode) => {\n if (\n node.forCount === curForNode.forCount + 1 &&\n dataBinds[node.id] &&\n dataBinds[node.id]._waFor\n ) {\n widgets[node.id]._disposers = { dataBinds: [] };\n const dispose = runFor(\n node,\n subForItems,\n widgets,\n node.parent && widgets[node.parent.id],\n context\n );\n curForNode.id && widgets[curForNode.id]._disposers.push(dispose);\n }\n });\n\n return widgets;\n }\n }\n}\n\n/**\n * Add parent, children to widget\n */\nfunction createWidgetTree(widgets, dataBinds) {\n const virtualRoot = { children: [], forCount: 0 };\n const nodes = Object.keys(widgets).reduce((result, id) => {\n result[id] = {\n id,\n value: widgets[id],\n children: [],\n parent: null,\n forCount: 0,\n };\n return result;\n }, {});\n\n // Create widgets tree API\n Object.keys(nodes).map((id) => {\n const curNode = nodes[id];\n const parent = nodes[widgets[id]._parentId];\n if (!parent) {\n virtualRoot.children.push(curNode);\n return;\n }\n curNode.parent = parent;\n parent.children.push(curNode);\n });\n\n virtualRoot.children.map(addForCount);\n\n // dfs, add forCount\n function addForCount(node) {\n if (node.parent) {\n node.forCount = node.parent.forCount;\n }\n if (dataBinds[node.id] && dataBinds[node.id]._waFor) {\n node.forCount++;\n }\n node.children.map(addForCount);\n }\n\n return virtualRoot;\n}\n\nfunction dfsTree(node, fn, parent) {\n node.value && fn(node, parent);\n node.children.map((e) => dfsTree(e, fn, node.value ? node : null));\n}\n\n// dispose autorun\nfunction disposeWidgets(widgets = []) {\n widgets.forEach((widget) => {\n const disposers = widget._disposers;\n if (disposers) {\n disposers.map((dispose) => dispose());\n disposers.splice(0, disposers.length);\n }\n disposeWidgets(widget.children);\n });\n}\n"
102
102
  }
103
103
  };
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/generator/util/common.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,aAAa,EACb,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,oBAAY,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAClE,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAQjE;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,CAAC,aAAa,EAAE,uBAAuB,KAAK,IAAI,QAazD;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM;;;;;;;;EAUvD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,WAE/B;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,WAErC;AAED,wBAAgB,QAAQ,CACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,QAoBrD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,CAE/C;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GACxB,MAAM,CAYR;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,OAAO,EACrB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1C,OAAO,CAgBT;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,aAAa,EAAE,EAC7B,WAAW,EAAE,YAAY,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAgC7B;AAED,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,kBAAkB,GACpC,oBAAoB,CAyBtB;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,GAAG;;;;GAyBrD;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eA2BvE;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,UAI/C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,UAAQ,UAQ5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAExC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/generator/util/common.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,aAAa,EACb,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,oBAAY,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAClE,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAQjE;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,CAAC,aAAa,EAAE,uBAAuB,KAAK,IAAI,QAazD;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM;;;;;;;;EAUvD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,WAE/B;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,WAErC;AAED,wBAAgB,QAAQ,CACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,QAoBrD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,CAE/C;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GACxB,MAAM,CAYR;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,OAAO,EACrB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1C,OAAO,CAgBT;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,aAAa,EAAE,EAC7B,WAAW,EAAE,YAAY,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAED,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,kBAAkB,GACpC,oBAAoB,CAyBtB;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,GAAG;;;;GAyBrD;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eA2BvE;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,UAI/C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,UAAQ,UAQ5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAExC"}
@@ -126,8 +126,10 @@ function getComponentsInfo(appBuildDir, dependencies, fileCodeMap) {
126
126
  });
127
127
  }
128
128
  else {
129
- yield Promise.all(components.map(({ name, meta, emitEvents, evnets = undefined }) => __awaiter(this, void 0, void 0, function* () {
130
- outputObj[materialName + ':' + name] = Object.assign(Object.assign({ isComposite }, meta), { events: evnets, emitEvents: emitEvents });
129
+ yield Promise.all(components.map(({ name, meta, emitEvents, events = undefined, compConfig }) => __awaiter(this, void 0, void 0, function* () {
130
+ outputObj[materialName + ':' + name] = Object.assign(Object.assign({ isComposite }, meta), { events,
131
+ emitEvents,
132
+ compConfig });
131
133
  })));
132
134
  }
133
135
  })));
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.receiveDataByLowcodeDiff = exports.evalExpression = void 0;
4
4
  function evalExpression(code, runtime) {
5
5
  try {
6
- return runtime.eval(`(function(forItems){const $for = forItems; return ${code};})`);
6
+ return runtime.eval(`(function(forItems, $context){const $for = forItems; return ${code};})`);
7
7
  }
8
8
  catch (e) {
9
9
  runtime.console.error(`Error in expression:\t${code}\n\n`, e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/framework-plugin-low-code",
3
- "version": "0.6.17",
3
+ "version": "0.6.18",
4
4
  "description": "云开发 Tencent CloudBase Framework Low Code Plugin,将低码配置生成完整项目并一键部署云开发资源。",
5
5
  "author": "yhsunshining@gmail.com",
6
6
  "homepage": "https://github.com/TencentCloudBase/cloudbase-framework#readme",
@@ -24,6 +24,8 @@ export const CompRenderer = observer(function (props) {
24
24
  genericComp = {},
25
25
  emitEvents = [],
26
26
  componentSchema = {},
27
+ context = {},
28
+ updateContext,
27
29
  } = props;
28
30
 
29
31
  const [blockIndex, setBlockIndex] = useState();
@@ -63,6 +65,14 @@ export const CompRenderer = observer(function (props) {
63
65
  // 组件最终用于执行的事件函数
64
66
  const emit = useCallback(
65
67
  (trigger, eventData, forItems, domEvent, scopeContext) => {
68
+ // 如果是数据容器,则将传过来的data,赋值给容器上下文context
69
+ if (
70
+ trigger === 'onDataChange' &&
71
+ componentSchema?.compConfig?.isDataContainer
72
+ ) {
73
+ updateContext(compId, eventData?.data);
74
+ }
75
+
66
76
  const listeners = listenerInstances;
67
77
  const event = {
68
78
  detail: eventData,
@@ -156,7 +166,7 @@ export const CompRenderer = observer(function (props) {
156
166
  // For循环渲染
157
167
  let forList;
158
168
  try {
159
- forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems);
169
+ forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems, undefined, context);
160
170
  } catch (e) {
161
171
  forList = [];
162
172
  console.error('_waFor data', e);
@@ -211,6 +221,15 @@ export const CompRenderer = observer(function (props) {
211
221
  ? get(widgetsData, forItemsIndexes)
212
222
  : widgetsData;
213
223
  const domRef = setGetDomApi(currentWidget, props);
224
+
225
+ // 判断为容器组件,则增加一个onDataChange事件
226
+ if (
227
+ componentSchema?.compConfig?.isDataContainer &&
228
+ !emitEvents?.includes('onDataChange')
229
+ ) {
230
+ emitEvents.push('onDataChange');
231
+ }
232
+
214
233
  return (
215
234
  <ForContext.Provider key={index} value={forItems}>
216
235
  <Field
@@ -283,6 +302,14 @@ export const CompRenderer = observer(function (props) {
283
302
  : widgetsData;
284
303
  const domRef = setGetDomApi(currentWidget, props);
285
304
 
305
+ // 判断为容器组件,则增加一个onDataChange事件
306
+ if (
307
+ componentSchema?.compConfig?.isDataContainer &&
308
+ !emitEvents?.includes('onDataChange')
309
+ ) {
310
+ emitEvents.push('onDataChange');
311
+ }
312
+
286
313
  return (
287
314
  <Field
288
315
  data={{
@@ -24,6 +24,8 @@ export function AppRender(props) {
24
24
  rootNode = true,
25
25
  codeContext,
26
26
  scopeContext = {},
27
+ context = {},
28
+ updateContext,
27
29
  } = props;
28
30
  const {
29
31
  'x-props': xProps,
@@ -91,6 +93,8 @@ export function AppRender(props) {
91
93
  virtualFields={virtualFields}
92
94
  codeContext={codeContext}
93
95
  scopeContext={clonedScopeContext}
96
+ context={context}
97
+ updateContext={updateContext}
94
98
  />
95
99
  );
96
100
  }
@@ -102,6 +106,8 @@ export function AppRender(props) {
102
106
  virtualFields={virtualFields}
103
107
  codeContext={codeContext}
104
108
  scopeContext={scopeContext}
109
+ context={context}
110
+ updateContext={updateContext}
105
111
  />
106
112
  );
107
113
  }
@@ -118,6 +124,8 @@ export function AppRender(props) {
118
124
  codeContext={codeContext}
119
125
  scopeContext={scopeContext}
120
126
  genericComp={genericComp}
127
+ context={context}
128
+ updateContext={updateContext}
121
129
  >
122
130
  {children.map((comp) => (
123
131
  <AppRender
@@ -128,6 +136,8 @@ export function AppRender(props) {
128
136
  virtualFields={virtualFields}
129
137
  codeContext={codeContext}
130
138
  scopeContext={scopeContext}
139
+ context={context}
140
+ updateContext={updateContext}
131
141
  />
132
142
  ))}
133
143
  </CompRenderer>
@@ -48,7 +48,7 @@ const virtualFields = {
48
48
  export default function App() {
49
49
  // 检查权限
50
50
  // const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);
51
-
51
+ const [context, setContext] = React.useState({});
52
52
  // 兼容 this.state / $page.state 两种模式
53
53
  const pageCodeContext = createPageApi()
54
54
  const $page = pageCodeContext
@@ -62,6 +62,27 @@ export default function App() {
62
62
  const dataBinds = $page._dataBinds = <%= dataBinds %>;
63
63
  const componentSchema = <%= componentSchema %>;
64
64
 
65
+ /**
66
+ * 更新数据容器的上下文的方法
67
+ * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
68
+ * 当组件卸载时,传过来的data为undefined即可
69
+ * {
70
+ * id1: [{...}],
71
+ * id2: {...},
72
+ * id3: undefined,
73
+ * id4: null,
74
+ * ...
75
+ * }
76
+ * @param id
77
+ * @param data
78
+ */
79
+ const updateContext = (id, data) => {
80
+ if(id) {
81
+ context[id] = { data };
82
+ }
83
+ setContext({ ...context });
84
+ }
85
+
65
86
  Object.assign($page, {
66
87
  id:'<%= pageName %>',
67
88
  state: observable(initPageState),
@@ -77,7 +98,7 @@ export default function App() {
77
98
  });
78
99
  };
79
100
 
80
- $page.widgets = createWidgets(widgetsContext, dataBinds)
101
+ $page.widgets = createWidgets(widgetsContext, dataBinds, context)
81
102
  // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds
82
103
  retryDataBinds()
83
104
 
@@ -116,6 +137,8 @@ export default function App() {
116
137
  virtualFields={virtualFields}
117
138
  componentSchema={componentSchema}
118
139
  codeContext={pageCodeContext}
140
+ context={context}
141
+ updateContext={updateContext}
119
142
  />
120
143
  </div>
121
144
  );
@@ -117,9 +117,9 @@ export function retryDataBinds(tryTime = 10) {
117
117
  }
118
118
  retryDataBinds(tryTime - 1);
119
119
  }
120
- export function createWidgets(widgetProps, dataBinds) {
120
+ export function createWidgets(widgetProps, dataBinds, context) {
121
121
  const nodeTree = createWidgetTree(widgetProps, dataBinds);
122
- const widgets = runFor(nodeTree, {}, null, null);
122
+ const widgets = runFor(nodeTree, {}, null, null, context);
123
123
  return widgets;
124
124
 
125
125
  /**
@@ -128,9 +128,10 @@ export function createWidgets(widgetProps, dataBinds) {
128
128
  * @param {*} forItems
129
129
  * @param {*} parentLevelWidgets
130
130
  * @param {*} parentWidget
131
+ * @param {*} context
131
132
  * @returns top level widgets or for dispose
132
133
  */
133
- function runFor(curForNode, forItems, parentLevelWidgets, parentWidget) {
134
+ function runFor(curForNode, forItems, parentLevelWidgets, parentWidget, context) {
134
135
  const nodeId = curForNode.id;
135
136
  if (!curForNode.value) {
136
137
  return createSubTree(curForNode, {});
@@ -138,7 +139,7 @@ export function createWidgets(widgetProps, dataBinds) {
138
139
  const dispose = autorun(() => {
139
140
  let forList = [];
140
141
  try {
141
- forList = dataBinds[nodeId]._waFor(forItems);
142
+ forList = dataBinds[nodeId]._waFor(forItems, undefined, context);
142
143
  } catch (e) {
143
144
  console.error('waFor error', e);
144
145
  }
@@ -268,7 +269,8 @@ export function createWidgets(widgetProps, dataBinds) {
268
269
  node,
269
270
  subForItems,
270
271
  widgets,
271
- node.parent && widgets[node.parent.id]
272
+ node.parent && widgets[node.parent.id],
273
+ context
272
274
  );
273
275
  curForNode.id && widgets[curForNode.id]._disposers.push(dispose);
274
276
  }
@@ -9,7 +9,7 @@ import sdk from './weapp-sdk'
9
9
  */
10
10
  export const compLowcodes = {}
11
11
 
12
- export function createComponent(key, behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps, index, lifeCycle, stateFn, computedFuncs, config, libCommonRes) {
12
+ export function createComponent(key, behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps, index, lifeCycle, stateFn, computedFuncs, config, libCommonRes, undefined, context) {
13
13
 
14
14
  compLowcodes[key] = {
15
15
  index,
@@ -41,9 +41,6 @@ export function createComponent(key, behaviors, properties, events, handler, dat
41
41
  },
42
42
  ...properties,
43
43
  },
44
-
45
- data: {},
46
-
47
44
  lifetimes: {
48
45
  created() {
49
46
  this._pageActive = true
@@ -55,7 +52,7 @@ export function createComponent(key, behaviors, properties, events, handler, dat
55
52
 
56
53
  $comp.props.events = createPropEvents(events, this)
57
54
  $comp.widgets = {}
58
- const { widgets, rootWidget: virtualRootWidget } = createWidgets(widgetProps, dataBindsBindContext(dataBinds, $comp), $comp.widgets, this)
55
+ const { widgets, rootWidget: virtualRootWidget } = createWidgets(widgetProps, dataBindsBindContext(dataBinds, $comp), $comp.widgets, context, this)
59
56
  this._virtualRootWidget = virtualRootWidget
60
57
 
61
58
  try {
@@ -13,6 +13,7 @@ export function createPage(
13
13
  dataBinds,
14
14
  app,
15
15
  $page,
16
+ context,
16
17
  ) {
17
18
  $page.state = observable(pageState);
18
19
  let dataset = createDataset($page.uuid);
@@ -47,7 +48,7 @@ export function createPage(
47
48
  attached() {
48
49
  // createWidgets 从上面移到这里是为了 i18n 切换语言的时候页面能生效
49
50
  $page.widgets = {};
50
- const { rootWidget, widgets } = createWidgets(widgetProps, dataBinds, $page.widgets);
51
+ const { rootWidget, widgets } = createWidgets(widgetProps, dataBinds, $page.widgets, context);
51
52
  this._rootWidget = rootWidget;
52
53
  this._widgets = widgets;
53
54
  this._pageActive = true;
@@ -34,9 +34,9 @@ export function resolveWidgetData(props) {
34
34
  }
35
35
 
36
36
 
37
- export function createWidgets(widgetProps, dataBinds, widgetHolder, ownerMpInst) {
37
+ export function createWidgets(widgetProps, dataBinds, widgetHolder, context, ownerMpInst) {
38
38
  const rootNode = createWidgetDataTree(widgetProps, dataBinds)
39
- return createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder)
39
+ return createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder, undefined, undefined, undefined, undefined, undefined, context)
40
40
  }
41
41
 
42
42
  /**
@@ -47,7 +47,7 @@ export function createWidgets(widgetProps, dataBinds, widgetHolder, ownerMpInst)
47
47
  */
48
48
  function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, widgetHolder = {},
49
49
  index = 0, forItems = {}, ownerForWidgetHolder = null,
50
- failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }) {
50
+ failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }, context = {}) {
51
51
  const indexPostfix = (forItems.lists || []).slice().reverse().map(list => idSeparator + list.currentIndex).join('')
52
52
 
53
53
  // traverse down the tree to set up all widgets
@@ -87,7 +87,7 @@ function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, wi
87
87
  if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
88
88
  // find the node bound with next level for
89
89
  const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent
90
- const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent)
90
+ const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent, context)
91
91
  parent._disposers.push(dispose) // Add the for bind dispose to the parent node of forNode
92
92
  }
93
93
  })
@@ -110,12 +110,12 @@ function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, wi
110
110
  * @param {*} parentWidget
111
111
  * @returns top level widgets or for dispose
112
112
  */
113
- function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent) {
113
+ function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent, context) {
114
114
  const nodeId = curForNode.id
115
115
  const dispose = autorun(() => {
116
116
  let forList = []
117
117
  try {
118
- forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById)
118
+ forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById, undefined, context)
119
119
  if (!Array.isArray(forList)) {
120
120
  forList = []
121
121
  }
@@ -153,7 +153,7 @@ function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, owner
153
153
  lists: [{ currentItem: item, currentIndex: index }, ...lists],
154
154
  itemsById: { ...itemsById, [nodeId]: item },
155
155
  }
156
- const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent)
156
+ const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent, context)
157
157
  rootWidget._forItems = _forItems
158
158
  })
159
159
  })
@@ -1,3 +1,4 @@
1
+ import { observable } from 'mobx';
1
2
  import { createComponent } from '../../../common/weapp-component'
2
3
  import { mpCompToWidget } from '../../../common/widget'
3
4
  import { concatClassList, px2rpx } from '../../../common/style'
@@ -11,6 +12,8 @@ import _handler<%= h %> from './lowcode/handler/<%= h %>' <%}) %>
11
12
  import * as constObj from '../libCommonRes/const'
12
13
  import * as toolsObj from '../libCommonRes/tools'
13
14
 
15
+ const context = observable({});
16
+
14
17
  const libCode = '<%= materialName %>'
15
18
 
16
19
  const widgetProps = <%= stringifyObj(widgetProps, {depth: null}) %>
@@ -21,7 +24,7 @@ const evtListeners = {<% Object.entries(eventHandlers).map(([handlerName, listen
21
24
  key: '<%= l.key %>',
22
25
  handler: <% if (l.type == 'rematch') {%> _handler<%= l.handler %> <%} else {%> <%= l.handler %> <%} %>,
23
26
  data: <%= stringifyObj(l.data, {depth: null}) %>,
24
- boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event) => {const $for=forItems;return <%= expr %>},
27
+ boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event, $context) => {const $for=forItems; return <%= expr %>},
25
28
  <%}) %>}
26
29
  },<%})%>
27
30
  ],<%})%>
@@ -49,11 +52,11 @@ const handler = {<% handlers.forEach(h => {%>
49
52
 
50
53
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
51
54
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
52
- <%= prop %>: function (lists, forItems, event) {const $for=forItems; return <%= expr %>; },<% }) %>
55
+ <%= prop %>: function (lists, forItems, event, $context) {const $for=forItems; return <%= expr %>; },<% }) %>
53
56
  },<%}) %>
54
57
  }
55
58
 
56
59
  const config = <%= JSON.stringify(config || {})%>
57
60
 
58
61
  createComponent('<%= key %>', behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps,
59
- index, lifeCycle, stateFn, computedFuncs, config, { const: constObj, tools: toolsObj }, libCode)
62
+ index, lifeCycle, stateFn, computedFuncs, config, { const: constObj, tools: toolsObj }, libCode, context)
@@ -3,7 +3,7 @@
3
3
  "version": "1.0.0",
4
4
  "scripts": { },
5
5
  "dependencies": {
6
- "@cloudbase/weda-cloud-sdk": "1.0.1",
6
+ "@cloudbase/weda-cloud-sdk": "1.0.1",
7
7
  "mobx": "^5.15.4",
8
8
  "lodash.get": "^4.4.2",
9
9
  "lodash.set": "^4.3.2",
@@ -1,3 +1,4 @@
1
+ import { observable } from 'mobx';
1
2
  import { createPage } from '<%= subLevelPath %>../../common/weapp-page'
2
3
  import { mpCompToWidget } from '<%= subLevelPath %>../../common/widget'
3
4
  import { concatClassList, px2rpx } from '<%= subLevelPath %>../../common/style'
@@ -8,6 +9,7 @@ import lifecyle from '../../lowcode/<%= pageName %>/lifecycle'
8
9
  import state from '../../lowcode/<%= pageName %>/state'
9
10
  import computed from '../../lowcode/<%= pageName %>/computed'
10
11
 
12
+ const context = observable({});
11
13
 
12
14
  const widgetProps = <%= stringifyObj(widgetProps, {depth: null}) %>
13
15
  /** widget event listeners **/
@@ -17,18 +19,18 @@ const evtListeners = {<% Object.entries(eventHanlders).map(([handlerName, listen
17
19
  key: '<%= l.key %>',
18
20
  handler: <% if (l.type === 'rematch') {%> handlers.<%= l.handler %> <%} else if (l.type == 'material') {%> function(...args) { return require('../../materials/<%= l.handlerModule %>/actions/<%= l.handler %>/index').default(...args) } <%} else {%> <%= l.handler %> <%} %>,
19
21
  data: <%= stringifyObj(l.data, {depth: null}) %>,
20
- boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event) => {const $for = forItems; return <%= expr %>},
22
+ boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event, $context) => {const $for = forItems; return <%= expr %>},
21
23
  <%}) %>}
22
24
  },<%})%>
23
25
  ],<%})%>
24
26
  }
25
27
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
26
28
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
27
- <%= prop %>: function (lists, forItems, event) {const $for = forItems; return <%= expr %>; },<% }) %>
29
+ <%= prop %>: function (lists, forItems, event, $context) {const $for = forItems; return <%= expr %>; },<% }) %>
28
30
  },<%}) %>
29
31
  }
30
32
 
31
33
  $page.id = '<%= pageName %>'
32
34
  $page.uuid = '<%= pageUUID %>'
33
35
  $page.handler = handlers
34
- createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page)
36
+ createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page, context)
@@ -24,6 +24,8 @@ export const CompRenderer = observer(function (props) {
24
24
  slots = {},
25
25
  codeContext,
26
26
  scopeContext,
27
+ context = {},
28
+ updateContext,
27
29
  emitEvents = [],
28
30
  componentSchema = {},
29
31
  } = props;
@@ -62,6 +64,13 @@ export const CompRenderer = observer(function (props) {
62
64
  // 组件最终用于执行的事件函数
63
65
  const emit = useCallback(
64
66
  (trigger, event, forItems, scopeContext) => {
67
+ // 如果是数据容器,则将传过来的data,赋值给容器上下文context
68
+ if (
69
+ trigger === 'onDataChange' &&
70
+ componentSchema?.compConfig?.isDataContainer
71
+ ) {
72
+ updateContext(compId, event?.data);
73
+ }
65
74
  const listeners = listenerInstances;
66
75
  event = { detail: event, name: trigger };
67
76
  forItems = {
@@ -142,7 +151,7 @@ export const CompRenderer = observer(function (props) {
142
151
  try {
143
152
  // 绑定了 for 变量,但计算值错误时,应当空数组兜底
144
153
  forList =
145
- dataBinds && dataBinds._waFor && (dataBinds._waFor(parentForItems) || []);
154
+ dataBinds && dataBinds._waFor && (dataBinds._waFor(parentForItems, undefined, context) || []);
146
155
  } catch (e) {
147
156
  // 计算值出错则使用空数组兜底
148
157
  forList = [];
@@ -197,6 +206,15 @@ export const CompRenderer = observer(function (props) {
197
206
  classNameList: forItemClassNameList,
198
207
  staticResourceAttribute,
199
208
  });
209
+
210
+ // 判断为容器组件,则增加一个onDataChange事件
211
+ if (
212
+ componentSchema?.compConfig?.isDataContainer &&
213
+ !emitEvents?.includes('onDataChange')
214
+ ) {
215
+ emitEvents.push('onDataChange');
216
+ }
217
+
200
218
  return (
201
219
  <ForContext.Provider key={index} value={forItems}>
202
220
  <Field
@@ -263,6 +281,15 @@ export const CompRenderer = observer(function (props) {
263
281
  classNameList: finalClassNameList,
264
282
  staticResourceAttribute,
265
283
  });
284
+
285
+ // 判断为容器组件,则增加一个onDataChange事件
286
+ if (
287
+ componentSchema?.compConfig?.isDataContainer &&
288
+ !emitEvents?.includes('onDataChange')
289
+ ) {
290
+ emitEvents.push('onDataChange');
291
+ }
292
+
266
293
  return (
267
294
  <Field
268
295
  data={{ ...fieldData, _selectableBlockEvents: _selectableBlockEventsWithItem }}
@@ -23,6 +23,8 @@ export function AppRender(props) {
23
23
  rootNode = true,
24
24
  codeContext,
25
25
  scopeContext = {},
26
+ context = {},
27
+ updateContext,
26
28
  } = props;
27
29
 
28
30
  const { 'x-props': xProps, properties = {} } = componentSchema;
@@ -89,6 +91,8 @@ export function AppRender(props) {
89
91
  virtualFields={virtualFields}
90
92
  codeContext={codeContext}
91
93
  scopeContext={clonedScopeContext}
94
+ context={context}
95
+ updateContext={updateContext}
92
96
  />
93
97
  );
94
98
  }
@@ -100,6 +104,8 @@ export function AppRender(props) {
100
104
  virtualFields={virtualFields}
101
105
  codeContext={codeContext}
102
106
  scopeContext={scopeContext}
107
+ context={context}
108
+ updateContext={updateContext}
103
109
  />
104
110
  );
105
111
  }
@@ -115,6 +121,8 @@ export function AppRender(props) {
115
121
  slots={slots}
116
122
  codeContext={codeContext}
117
123
  scopeContext={scopeContext}
124
+ context={context}
125
+ updateContext={updateContext}
118
126
  >
119
127
  {children.map((comp) => (
120
128
  <AppRender
@@ -125,6 +133,8 @@ export function AppRender(props) {
125
133
  virtualFields={virtualFields}
126
134
  codeContext={codeContext}
127
135
  scopeContext={scopeContext}
136
+ context={context}
137
+ updateContext={updateContext}
128
138
  />
129
139
  ))}
130
140
  </CompRenderer>
@@ -94,9 +94,9 @@ export function retryDataBinds(tryTime = 10) {
94
94
  retryDataBinds(tryTime - 1);
95
95
  }, 0);
96
96
  }
97
- export function createWidgets(widgetProps, dataBinds, scopeContext = {}) {
97
+ export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context = {}) {
98
98
  const nodeTree = createWidgetTree(widgetProps, dataBinds);
99
- const widgets = runFor(nodeTree, {}, null, null, scopeContext);
99
+ const widgets = runFor(nodeTree, {}, null, null, scopeContext, context);
100
100
  return widgets;
101
101
 
102
102
  /**
@@ -106,6 +106,7 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}) {
106
106
  * @param {*} parentLevelWidgets
107
107
  * @param {*} parentWidget
108
108
  * @param {*} scopeContext
109
+ * @param {*} context
109
110
  * @returns top level widgets or for dispose
110
111
  */
111
112
  function runFor(
@@ -113,7 +114,8 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}) {
113
114
  forItems,
114
115
  parentLevelWidgets,
115
116
  parentWidget,
116
- scopeContext
117
+ scopeContext,
118
+ context,
117
119
  ) {
118
120
  const nodeId = curForNode.id;
119
121
  if (!curForNode.value) {
@@ -122,7 +124,7 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}) {
122
124
  const dispose = autorun(() => {
123
125
  let forList = [];
124
126
  try {
125
- forList = dataBinds[nodeId]._waFor(forItems, undefined, scopeContext);
127
+ forList = dataBinds[nodeId]._waFor(forItems, undefined, context);
126
128
  } catch (e) {
127
129
  console.warn('waFor error', e);
128
130
  }
@@ -247,7 +249,8 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}) {
247
249
  subForItems,
248
250
  widgets,
249
251
  node.parent && widgets[node.parent.id],
250
- scopeContext
252
+ scopeContext,
253
+ context
251
254
  );
252
255
  curForNode.id && widgets[curForNode.id]._disposers.push(dispose);
253
256
  }
@@ -64,6 +64,27 @@ initLifeCycle({
64
64
  export default function App() {
65
65
  // 检查权限
66
66
  const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);
67
+ const context = React.useRef(observable({})).current;
68
+
69
+ /**
70
+ * 更新数据容器的上下文的方法
71
+ * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
72
+ * 当组件卸载时,传过来的data为undefined即可
73
+ * {
74
+ * id1: [{...}],
75
+ * id2: {...},
76
+ * id3: undefined,
77
+ * id4: null,
78
+ * ...
79
+ * }
80
+ * @param id
81
+ * @param data
82
+ */
83
+ const updateContext = (id, data) => {
84
+ if (id) {
85
+ context[id] = { data };
86
+ }
87
+ }
67
88
 
68
89
  React.useEffect(() => {
69
90
  checkAuth(app, app.id, '<%= pageName %>').then((checkAuthResult) => {
@@ -86,12 +107,13 @@ export default function App() {
86
107
  app.utils.set($page.dataset.state, keyPath, userSetState[keyPath]);
87
108
  });
88
109
  };
110
+ }, []);
89
111
 
90
- $page.widgets = createWidgets(widgetsContext, dataBinds, {});
112
+ React.useEffect(() => {
113
+ $page.widgets = createWidgets(widgetsContext, dataBinds, {}, context);
91
114
  // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds
92
115
  retryDataBinds();
93
- }, []);
94
-
116
+ }, [context]);
95
117
 
96
118
  // Web 环境页面级别生命周期
97
119
  if (!process.env.isMiniprogram) {
@@ -115,6 +137,8 @@ export default function App() {
115
137
  <AppRender pageListenerInstances={pageListenerInstances}
116
138
  virtualFields={virtualFields}
117
139
  componentSchema={componentSchema}
140
+ context={context}
141
+ updateContext={updateContext}
118
142
  />)}
119
143
  </div>
120
144
  );