@cloudbase/framework-plugin-low-code 0.6.59 → 0.6.63

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.
package/README.md CHANGED
@@ -102,3 +102,24 @@ cloudbase framework:deploy
102
102
  - 云开发官网地址: [https://cloudbase.net/](https://cloudbase.net/)
103
103
  - 云开发静态网站开通指南:[https://docs.cloudbase.net/hosting/](https://docs.cloudbase.net/hosting/)
104
104
  - 云开发控制台地址: [https://console.cloud.tencent.com/tcb](https://console.cloud.tencent.com/tcb)
105
+
106
+ ## 本地测试
107
+
108
+ 1. 需要先 link framework。简单可以 clone http://git.code.oa.com/QBase/cloudbase-framework-plugin-low-code.git,切换 release/cals_v2 分支,执行命令,完成 framework-core 的 link;
109
+
110
+ ```bash
111
+ yarn
112
+ yarn run bootstrap
113
+ yarn run build
114
+ yarn run link
115
+
116
+ ```
117
+
118
+ 1. link low-code-plugin。在本目录执行命令,完成 framework 的 link
119
+ ```
120
+ yarn
121
+ yarn run build
122
+ yarn run link
123
+ ```
124
+ 1. 本地开发 通过 `yarn run dev` 监听文件变化并 ts 编译。
125
+ 1. `__test__/sample` 目录中有测试项目,通过添加 `.env` 文件可指定 mpAppId /ENV_ID 以及 SECRET 等环境变量。`input.json` 为低码配置,`yarn run dev` 进行文件生成及发布。
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EACb,UAAU,EAEV,OAAO,EAIR,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAEL,SAAS,EACT,YAAY,EACZ,UAAU,EACX,MAAM,iBAAiB,CAAC;AAUzB,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,OAAO,EACP,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,EACT,OAAO,EACP,aAAa,GACd,EAAE;IACD,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,aAAa,EAAE,SAAS,EAAE,CAAC;CAC5B,GAAG,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,CAuSvC;AA8KD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,aAAa,iBAgCnB;AAYD,wBAAgB,oBAAoB,CAAC,EACnC,YAAY,EACZ,MAAM,EACN,SAAS,GACV,EAAE;IACD,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;;;EA0CA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/mp/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EACb,UAAU,EAEV,OAAO,EAIR,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAEL,SAAS,EACT,YAAY,EACZ,UAAU,EACX,MAAM,iBAAiB,CAAC;AAUzB,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,OAAO,EACP,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,EACT,OAAO,EACP,aAAa,GACd,EAAE;IACD,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,aAAa,EAAE,SAAS,EAAE,CAAC;CAC5B,GAAG,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,CAuSvC;AAiLD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,aAAa,iBAgCnB;AAYD,wBAAgB,oBAAoB,CAAC,EACnC,YAAY,EACZ,MAAM,EACN,SAAS,GACV,EAAE;IACD,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;;;EA0CA"}
@@ -248,7 +248,7 @@ function generatePkg(weapp, appRoot, ctx, pageConfigs) {
248
248
  console.log('Generating ' + em('page') + ' files');
249
249
  generateFiles_1.cleanDir(path_1.default.join(appRoot, 'pages'), []);
250
250
  yield Promise.all(weapp.pageInstanceList.map((page) => __awaiter(this, void 0, void 0, function* () {
251
- var _a;
251
+ var _a, _b;
252
252
  const rootPath = weapp.rootPath || '';
253
253
  const usingComponents = {};
254
254
  const wxml = wxml_1.generateWxml(page.componentInstances, `Page ${rootPath ? path_1.default.join(rootPath, 'pages') : ''}/${page.id}`, wxmlDataPrefix, Object.assign(Object.assign({}, ctx), { rootPath, isPage: true }), usingComponents);
@@ -261,6 +261,7 @@ function generatePkg(weapp, appRoot, ctx, pageConfigs) {
261
261
  pageSource: page.data.src || '',
262
262
  eventHanlders: util_2.createEventHanlders(page.componentInstances, '$page', ctx),
263
263
  dataBinds: util_2.createDataBinds(page.componentInstances, ctx),
264
+ pageAttributes: Object.assign({}, (((_a = page.data) === null || _a === void 0 ? void 0 : _a.appShareMessage) ? { 'appShareMessage': page.data.appShareMessage.value } : {})),
264
265
  debug: !ctx.isProduction,
265
266
  stringifyObj: util_1.inspect,
266
267
  subLevelPath: rootPath ? path_2.default.relative(rootPath, '') + '/' : '',
@@ -273,7 +274,7 @@ function generatePkg(weapp, appRoot, ctx, pageConfigs) {
273
274
  content: wxml,
274
275
  },
275
276
  [`index.wxss|${pageFileName}.wxss`]: {
276
- subWxss: rootPath && !((_a = ctx.mainAppData) === null || _a === void 0 ? void 0 : _a.mpPkgUrl)
277
+ subWxss: rootPath && !((_b = ctx.mainAppData) === null || _b === void 0 ? void 0 : _b.mpPkgUrl)
277
278
  ? `@import "${path_2.default.relative(`/${rootPath}/pages/${page.id}`, '/lowcode')}/style.wxss";`
278
279
  : '',
279
280
  content: weapps_core_1.toCssText(weapps_core_1.toCssStyle(page.commonStyle, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AACpD,OAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAUrE,OAAO,EACL,SAAS,EAET,cAAc,EAIf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAYvD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAgB,MAAM,SAAS,CAAC;AAM7D,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,2BAA2B,IAAK,CAAC;AAoB9C,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;CAoBnB,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAM5C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAMhB,OAAO,CAAC,EAAE,OAAO,CAAC;IAIlB,KAAK,EAAE,MAAM,CAAC;IAId,oBAAoB,EAAE,GAAG,CAAC;IAI1B,uBAAuB,CAAC,EAAE,GAAG,EAAE,CAAC;IAIhC,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;IAK/B,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAK5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAIhC,OAAO,CAAC,EAAE,MAAM,CAAC;IAIjB,cAAc,CAAC,EAAE,MAAM,CAAC;IAIxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IAIpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAK5B,aAAa,EAAE;QAIb,IAAI,EAAE,WAAW,CAAC;QAIlB,OAAO,CAAC,EAAE,MAAM,CAAC;QAIjB,WAAW,CAAC,EAAE,MAAM,CAAC;QAIrB,OAAO,CAAC,EAAE,MAAM,CAAC;QAIjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAI5B,aAAa,CAAC,EAAE,MAAM,CAAC;QAIvB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAKF,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAIlB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAKF,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAIF,SAAS,CAAC,EAAE;QACV,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,GAAG,CAAC;KAChB,CAAC;IAIF,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,oBAAY,cAAc,GAAG,6BAA6B,GACxD,OAAO,cAAc,CAAC;AAExB,cAAM,aAAc,SAAQ,MAAM;IAmBvB,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,gBAAgB;IACrB,MAAM,EAAE,6BAA6B;IApB9C,SAAS,CAAC,eAAe,EAAE,cAAc,CAAC;IAC1C,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,WAAW,MAAC;IACtB,SAAS,CAAC,mBAAmB,MAAC;IAC9B,SAAS,CAAC,UAAU,MAAC;IACrB,SAAS,CAAC,eAAe,MAAC;IAC1B,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,QAAQ,KAAM;IACxB,SAAS,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC;IAClC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAM;IAC9B,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC;IACxB,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IACtB,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC;IAC/B,SAAS,CAAC,cAAc,CAAC,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;gBAEO,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,6BAA6B;IA8J9C,QAAQ;IAMR,qBAAqB,CAAC,aAAa,EAAE,cAAc;IAmGnD,eAAe;IAUf,KAAK,CAAC,KAAK,KAAA;IASX,QAAQ,CAAC,KAAK,KAAA;IAWR,IAAI;IAKJ,GAAG;IAKH,MAAM;IAKN,OAAO;IAKP,KAAK;IAqTL,OAAO;IA8GP,MAAM;IA4HN,qBAAqB,CAAC,OAAO,EAAE,MAAM;IA8CrC,mBAAmB,CAAC,KAAK,KAAA,EAAE,KAAK,GAAE,OAAe;IAgBjD,eAAe,CAAC,KAAK,KAAA,EAAE,KAAK,GAAE,OAAe;IAqBnD,eAAe,CAAC,OAAO,KAAA;IAIjB,gBAAgB;IA4HhB,2BAA2B;IAuE3B,UAAU;IAwBV,OAAO,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA;IAejB,uBAAuB;IA4DvB,yBAAyB;IA0F/B,oBAAoB;CAOrB;AAgCD,eAAO,MAAM,MAAM,sBAAgB,CAAC"}
@@ -6,7 +6,7 @@ export declare function originJsonToFileList(appData: IWeAppData): (import("../t
6
6
  code: string;
7
7
  pageId: string;
8
8
  })[];
9
- export declare function getExtByType(type: CodeType): ".less" | ".js" | ".json";
9
+ export declare function getExtByType(type: CodeType): ".js" | ".json" | ".less";
10
10
  export declare function HACK_FIX_LOWCODE_IN(code?: string): string;
11
11
  export declare function HACK_FIX_LOWCODE_OUT(code?: string): string;
12
12
  //# sourceMappingURL=file.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/framework-plugin-low-code",
3
- "version": "0.6.59",
3
+ "version": "0.6.63",
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",
@@ -51,7 +51,7 @@ export function createEventHandlers(evtListeners, context) {
51
51
  detail: res
52
52
  })
53
53
  } catch (e) {
54
- let eventName = l.key ? `${l.key}_fail` : ''
54
+ let eventName = l.key ? `${prefix}$${l.key}_fail` : ''
55
55
  if(self[eventName]){
56
56
  await self[eventName]({
57
57
  ...event,
@@ -14,6 +14,7 @@ export function createPage(
14
14
  app,
15
15
  $page,
16
16
  context,
17
+ pageAttributes
17
18
  ) {
18
19
  const evtHandlers = createEventHandlers(evtListeners, context);
19
20
 
@@ -32,6 +33,18 @@ export function createPage(
32
33
  if (res?.from === 'button' && res?.target?.dataset?.weda_share_info) {
33
34
  return res?.target?.dataset?.weda_share_info;
34
35
  }
36
+ if (res?.from === 'menu' && pageAttributes?.appShareMessage) {
37
+ let { enable, pageId, params, imageUrl, title } = pageAttributes.appShareMessage;
38
+ if (enable) {
39
+ pageId = pageId ? pageId.replace(/^(\.)?\//, '') : pageId;
40
+ let realPath = `/pages/${pageId}/index` + (params ? '?' + params.map(pair => pair.key + '=' + pair.value).join('&') : '');
41
+ return {
42
+ path: realPath,
43
+ imageUrl,
44
+ title
45
+ };
46
+ }
47
+ }
35
48
  try {
36
49
  return lifecycle?.['onShareAppMessage']?.() || {};
37
50
  } catch (error) {
@@ -119,7 +132,7 @@ export function createPage(
119
132
  },
120
133
 
121
134
  getWeAppInst() {
122
- if(!this.$WEAPPS_PAGE){
135
+ if (!this.$WEAPPS_PAGE) {
123
136
  $page.state = observable(pageState);
124
137
  let dataset = createDataset($page.uuid);
125
138
  $page.dataset = dataset;
@@ -34,7 +34,9 @@ const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
34
34
  },<%}) %>
35
35
  }
36
36
 
37
+ const pageAttributes = <%= pageAttributes?JSON.stringify(pageAttributes):'{}' %>
38
+
37
39
  $page.id = '<%= pageName %>'
38
40
  $page.uuid = '<%= pageUUID %>'
39
41
  $page.handler = handlers
40
- createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page, context)
42
+ createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page, context,pageAttributes)
@@ -7,7 +7,7 @@ import { get, set } from 'lodash';
7
7
  import { $page } from '../../app/global-api';
8
8
  import { getDom } from '../utils/widgets';
9
9
  import { checkVisible } from '../../utils/index';
10
- import { generateSlotMetaMap } from '../render';
10
+ import { getComponentChildren, generateSlotMetaMap } from '../render';
11
11
 
12
12
  export const ForContext = createContext({});
13
13
 
@@ -35,275 +35,434 @@ function generateSlotMap(slots, forContext = undefined) {
35
35
  return map;
36
36
  }
37
37
 
38
- export const CompRenderer = observer(function (props) {
39
- const {
40
- id: compId,
41
- xProps,
42
- virtualFields,
43
- renderSlot,
44
- codeContext,
45
- scopeContext,
46
- context = {},
47
- updateContext,
48
- emitEvents = [],
49
- componentSchema = {},
50
- } = props;
51
-
52
- const indexRef = useRef();
53
- const typeRef = useRef();
38
+ function getSafeComponentProps({ style, classNameList }) {
39
+ const componentProps = {};
54
40
 
55
- const isInComposite = !!props.codeContext;
56
- // 判断 widgets 是从 page 来的,还是组件来的
57
- const widgetsData = !isInComposite
58
- ? $page.widgets[compId]
59
- : codeContext.$WEAPPS_COMP.widgets[compId];
60
-
61
- if (!xProps) {
62
- return props.children;
41
+ if (classNameList.length) {
42
+ componentProps.className = classNameList.join(' ');
63
43
  }
64
44
 
65
- const {
66
- commonStyle = {},
67
- sourceKey,
68
- data = {},
69
- dataBinds,
70
- listenerInstances,
71
- styleBind,
72
- classNameList = [],
73
- classNameListBind,
74
- staticResourceAttribute = [],
75
- } = xProps;
76
- const Field = virtualFields[sourceKey];
77
- const parentForItems = useContext(ForContext);
78
-
79
- const _context = {
80
- scopeContext,
81
- forContext: parentForItems,
82
- codeContext,
83
- dataContext: context,
84
- };
45
+ if (style && Object.keys(style).length) {
46
+ componentProps.style = style;
47
+ }
48
+ return componentProps;
49
+ }
85
50
 
86
- // 组件最终用于执行的事件函数
87
- const emit = useCallback(
88
- (trigger, eventDetail, forItems, scopeContext) => {
89
- const listeners = listenerInstances || [];
90
-
91
- // 如果是数据容器,则将传过来的data,赋值给容器上下文context
92
- if (
93
- componentSchema?.compConfig?.isDataContainer &&
94
- !listeners?.some((listener) => listener.trigger === 'onDataChange')
95
- ) {
96
- listeners?.push({
97
- key: `wa${Date.now().toString().slice(-8)}`,
98
- trigger: 'onDataChange',
99
- isCapturePhase: false,
100
- data: {},
101
- dataBinds: {},
102
- instanceFunction: ({ event }) => {
103
- return updateContext(compId, event?.detail?.data);
104
- },
105
- });
51
+ // TODO: 需要不断移除 dataBinds(style/classList)
52
+ function getBindData({
53
+ widgetData,
54
+ forItems,
55
+ scopeContext,
56
+ codeContext,
57
+ commonStyle = {},
58
+ classNameList = [],
59
+ }) {
60
+ // bindData
61
+ if (Array.isArray(widgetData)) {
62
+ widgetData =
63
+ forItems.forIndexes === void 0 || widgetData.length === 0
64
+ ? {}
65
+ : get(widgetData, getForIndexes(forItems, widgetData));
66
+ }
67
+ widgetData = widgetData || {};
68
+ const fieldData = { ...widgetData };
69
+
70
+ const isRootNode = widgetData && !widgetData.parent;
71
+ const isInComposite = !!codeContext;
72
+
73
+ // 再次计算 scope value
74
+ for (let key in fieldData) {
75
+ if (Object.prototype.hasOwnProperty.call(fieldData, key)) {
76
+ const value = fieldData[key];
77
+ if (value && value.__type === 'scopedValue') {
78
+ try {
79
+ fieldData[key] = value.getValue(scopeContext);
80
+ } catch (e) {
81
+ console.warn(`Error computing data bind '${key}' error:`, e);
82
+ fieldData[key] = '';
83
+ }
106
84
  }
85
+ }
86
+ }
107
87
 
108
- let event = { detail: eventDetail, name: trigger };
109
- forItems = {
110
- ...forItems,
111
- forIndexes: getForIndexes(forItems, widgetsData),
112
- };
113
- emitEvent(
114
- trigger,
115
- listeners,
116
- {
117
- event,
118
- customEventData: event,
119
- forItems,
120
- },
121
- scopeContext,
122
- context
123
- );
124
- },
125
- [props]
126
- );
127
-
128
- // 选区最终用于执行的事件函数
129
- const emitSB = useCallback(
130
- (trigger, eventDetail, forItems, scopeContext, fieldData) => {
131
- const listeners =
132
- indexRef?.current !== undefined &&
133
- typeRef?.current &&
134
- fieldData?.[typeRef.current]?.[indexRef.current]?.selectableBlock?.[
135
- 'x-props'
136
- ]?.listenerInstances;
137
- let event = { detail: eventDetail, name: trigger };
138
- forItems = {
139
- ...forItems,
140
- forIndexes: getForIndexes(forItems, widgetsData),
141
- };
142
- emitEvent(
143
- trigger,
144
- listeners,
145
- {
146
- event,
147
- customEventData: event,
148
- forItems,
149
- },
150
- scopeContext,
151
- context
152
- );
153
- },
154
- [props]
155
- );
88
+ // bindStyle
89
+ let bindStyle = fieldData.style || {};
90
+ // 复合组件第一层需要将最外层样式 style 挂到节点上
91
+ let cssStyle = commonStyle || {};
92
+ if (isInComposite && isRootNode) {
93
+ cssStyle = {
94
+ ...cssStyle,
95
+ ...(codeContext.$WEAPPS_COMP.props?.style || {}),
96
+ };
97
+ bindStyle = {
98
+ ...bindStyle,
99
+ ...(codeContext.$WEAPPS_COMP.props?.style || {}),
100
+ };
101
+ }
102
+ const finalStyle = getFinalStyle(cssStyle, bindStyle);
156
103
 
157
- function getSafeComponentProps({
158
- style,
104
+ // bindClassList
105
+ const bindClassList = fieldData.classList || [];
106
+ const finalClassNameList = getFinalClassNameList(
159
107
  classNameList,
160
- staticResourceAttribute,
161
- }) {
162
- const componentProps = {};
163
- if (classNameList.length) {
164
- componentProps.className = classNameList.join(' ');
165
- }
108
+ bindClassList
109
+ );
166
110
 
167
- if (style && Object.keys(style).length) {
168
- componentProps.style = style;
169
- }
170
- if (staticResourceAttribute && staticResourceAttribute.length > 0) {
171
- componentProps.staticResourceAttribute = staticResourceAttribute;
111
+ // 当前在复合组件中,且当前节点为根节点
112
+ if (isInComposite && isRootNode) {
113
+ if (widgetData.ownerWidget) {
114
+ Object.keys(widgetData.ownerWidget).forEach((propName) => {
115
+ if (
116
+ propName === 'role' ||
117
+ ['aria-', 'data-'].some((prefix) => propName.startsWith(prefix))
118
+ ) {
119
+ widgetData[propName] = widgetData.ownerWidget[propName];
120
+ }
121
+ });
172
122
  }
173
- return componentProps;
174
123
  }
175
124
 
176
- // 选区的预览的click事件
177
- const onCustomEvent = ({ order: index, blockKey }) => {
178
- if (index !== undefined) {
179
- indexRef.current = index;
180
- typeRef.current = blockKey;
181
- }
125
+ // 防止渲染时 data 的 style 与实际的 style 冲突
126
+ delete fieldData.style;
127
+
128
+ return {
129
+ fieldData,
130
+ finalStyle,
131
+ finalClassNameList: Array.from(new Set(finalClassNameList)),
182
132
  };
133
+ }
134
+
135
+ function getForList(compId, dataBinds, parentForItems, dataContext) {
136
+ /**
137
+ * For循环渲染
138
+ * @important
139
+ * @default undfined // 代表没有进行for循环绑定
140
+ */
141
+ let forList = undefined;
183
142
 
184
- // For循环渲染
185
- let forList;
186
143
  try {
187
144
  // 绑定了 for 变量,但计算值错误时,应当空数组兜底
188
145
  forList =
189
146
  dataBinds &&
190
147
  dataBinds._waFor &&
191
- (dataBinds._waFor(parentForItems, undefined, context) || []);
148
+ (dataBinds._waFor(parentForItems, undefined, dataContext) || []);
192
149
  } catch (e) {
193
150
  // 计算值出错则使用空数组兜底
194
151
  forList = [];
195
152
  console.warn('_waFor data', e);
196
153
  }
154
+
155
+ // 绑定了for 并且计算了值,但是不是数组类型,应该进行兜底
197
156
  if (forList) {
198
157
  if (!Array.isArray(forList)) {
199
158
  console.warn(`${compId}循环绑定非数组值:`, forList);
200
159
  forList = [];
201
160
  }
202
- return forList.map((item, index) => {
203
- const forItemsIndexes = (parentForItems.forIndexes || []).concat(index);
204
- const forItems = {
205
- ...parentForItems,
206
- [compId]: item,
207
- forIndexes: forItemsIndexes,
208
- };
209
- const {
210
- fieldData: forItemData,
211
- finalStyle: forItemStyle,
212
- finalClassNameList: forItemClassNameList,
213
- } = getBindData(forItems, scopeContext);
214
- if (!checkVisible(forItemData)) {
215
- return null;
161
+ }
162
+
163
+ return forList;
164
+ }
165
+
166
+ function FieldWrapper({
167
+ Field,
168
+ componentSchema,
169
+ id,
170
+ data,
171
+ style = {},
172
+ className = '',
173
+ events,
174
+ compositeParent,
175
+ context,
176
+ children,
177
+ updateContext,
178
+ }) {
179
+ const {
180
+ scopeContext,
181
+ forContext,
182
+ forIndexes,
183
+ widgetsData,
184
+ codeContext,
185
+ dataContext,
186
+ } = context;
187
+
188
+ const injectContext = {};
189
+ const indexRef = React.useRef();
190
+ const typeRef = React.useRef();
191
+ const { 'x-props': xProps } = componentSchema;
192
+ let { staticResourceAttribute = [], listenerInstances = [] } = xProps;
193
+
194
+ // 组件最终用于执行的事件函数
195
+ const emit = React.useCallback(
196
+ (trigger, listeners, eventData, forItems, domEvent, scopeContext) => {
197
+ // 当组件是数据容器并且listeners未含有onDataChange事件时,增加一个onDataChange事件
198
+ if (componentSchema?.compConfig?.isDataContainer) {
199
+ listeners = listeners.concat({
200
+ key: `wa${Date.now().toString().slice(-8)}`,
201
+ trigger: 'onDataChange',
202
+ isCapturePhase: false,
203
+ data: {},
204
+ dataBinds: {},
205
+ instanceFunction: ({ event }) => {
206
+ return updateContext(id, event?.detail?.data);
207
+ },
208
+ });
216
209
  }
217
210
 
218
- const slotMap = generateSlotMap(
219
- generateSlotMetaMap(
220
- componentSchema,
211
+ if (injectContext?.emit) {
212
+ return injectContext.emit(
213
+ trigger,
214
+ listeners,
215
+ eventData,
216
+ forItems,
217
+ domEvent,
218
+ scopeContext
219
+ );
220
+ } else {
221
+ const event = {
222
+ detail: eventData,
223
+ name: trigger,
224
+ target: widgetsData,
225
+ currentTarget: widgetsData,
226
+ domEvent,
227
+ };
228
+ forItems = {
229
+ ...forItems,
230
+ forIndexes: getForIndexes(forItems, widgetsData),
231
+ };
232
+ emitEvent(
233
+ trigger,
234
+ listeners,
221
235
  {
222
- ..._context,
223
- forContext: forItems,
224
- virtualFields,
225
- updateContext,
236
+ event,
237
+ customEventData: event,
238
+ forItems,
239
+ domEvent,
226
240
  },
227
- {
228
- renderSlot,
229
- }
230
- )
231
- );
232
-
233
- const emitWithForItems = (trigger, evt) =>
234
- emit(trigger, evt, forItems, scopeContext);
235
-
236
- const _selectableBlockEventsForItems = {
237
- onCustomEvent,
238
- events:
239
- componentSchema?.selectableBlock?.events.map((item) => item.name) ||
240
- [],
241
- emit: (trigger, evt) =>
242
- emitSB(trigger, evt, forItems, scopeContext, forItemData),
243
- };
244
-
245
- delete forItemData.style;
246
-
247
- // 获取当前元素的 ref
248
- const currentWidget = Array.isArray(widgetsData)
249
- ? get(widgetsData, forItemsIndexes)
250
- : widgetsData;
251
- const domRef = setGetDomApi(currentWidget, isInComposite);
252
-
253
- const componentProps = getSafeComponentProps({
254
- style: forItemStyle,
255
- classNameList: forItemClassNameList,
256
- staticResourceAttribute,
257
- });
258
-
259
- // 判断为容器组件,则增加一个onDataChange事件
260
- if (
261
- componentSchema?.compConfig?.isDataContainer &&
262
- !emitEvents?.includes('onDataChange')
263
- ) {
264
- emitEvents.push('onDataChange');
241
+ scopeContext,
242
+ dataContext
243
+ );
265
244
  }
245
+ },
246
+ [widgetsData]
247
+ );
266
248
 
267
- return (
268
- <ForContext.Provider key={index} value={forItems}>
269
- <Field
270
- data={{
271
- ...forItemData,
272
- ...slotMap,
273
- _selectableBlockEvents: _selectableBlockEventsForItems,
274
- }}
275
- id={compId}
276
- {...componentProps}
277
- emit={emitWithForItems}
278
- events={emitEvents}
279
- compositeParent={codeContext}
280
- forIndexes={forItemsIndexes}
281
- $node={currentWidget}
282
- domRef={domRef}
283
- >
284
- {props.children}
285
- </Field>
286
- </ForContext.Provider>
287
- );
288
- });
249
+ const currentWidget = Array.isArray(widgetsData)
250
+ ? get(widgetsData, forIndexes)
251
+ : widgetsData;
252
+
253
+ if (!Array.isArray(staticResourceAttribute)) {
254
+ staticResourceAttribute = [];
289
255
  }
290
256
 
291
- // 单节点渲染
292
- const { fieldData, finalClassNameList, finalStyle } = getBindData(
293
- parentForItems,
294
- scopeContext
257
+ // 判断为容器组件,则增加一个onDataChange事件
258
+ if (
259
+ componentSchema?.compConfig?.isDataContainer &&
260
+ !events?.includes('onDataChange')
261
+ ) {
262
+ events.push('onDataChange');
263
+ }
264
+
265
+ return (
266
+ <Field
267
+ data={{
268
+ ...data,
269
+ _selectableBlockEvents: {
270
+ onCustomEvent: ({ order: index, blockKey }) => {
271
+ if (index !== undefined) {
272
+ indexRef.current = index;
273
+ typeRef.current = blockKey;
274
+ }
275
+ },
276
+ events:
277
+ componentSchema?.selectableBlock?.events.map((item) => item.name) ||
278
+ [],
279
+ emit: (trigger, evt, domEvent) =>
280
+ emit(
281
+ trigger,
282
+ indexRef?.current !== undefined &&
283
+ typeRef?.current &&
284
+ data?.[typeRef.current]?.[indexRef.current]?.selectableBlock?.[
285
+ 'x-props'
286
+ ]?.listenerInstances,
287
+ evt,
288
+ forContext,
289
+ domEvent,
290
+ scopeContext
291
+ ),
292
+ },
293
+ }}
294
+ id={id}
295
+ emit={(trigger, eventData, domEvent) =>
296
+ emit(
297
+ trigger,
298
+ listenerInstances,
299
+ eventData,
300
+ forContext,
301
+ domEvent,
302
+ scopeContext
303
+ )
304
+ }
305
+ events={events}
306
+ compositeParent={compositeParent}
307
+ forIndexes={forIndexes}
308
+ $node={currentWidget}
309
+ domRef={setGetDomApi(currentWidget, { codeContext })}
310
+ style={style}
311
+ className={className}
312
+ staticResourceAttribute={staticResourceAttribute}
313
+ >
314
+ {children}
315
+ </Field>
295
316
  );
296
- const emitWithForItems = (trigger, evt) =>
297
- emit(trigger, evt, parentForItems, scopeContext);
298
-
299
- const _selectableBlockEventsWithItem = {
300
- onCustomEvent,
301
- events:
302
- componentSchema?.selectableBlock?.events.map((item) => item.name) || [],
303
- emit: (trigger, evt) =>
304
- emitSB(trigger, evt, parentForItems, scopeContext, fieldData),
317
+ }
318
+
319
+ export const CompRenderer = observer(function (props) {
320
+ return getComponentRenderList({
321
+ ...props,
322
+ forContext: React.createContext(ForContext),
323
+ injectContext: {},
324
+ });
325
+ });
326
+
327
+ export function getComponentRenderList(props) {
328
+ const {
329
+ key = undefined,
330
+ id: compId,
331
+ xProps,
332
+ virtualFields,
333
+ renderSlot,
334
+ codeContext,
335
+ scopeContext,
336
+ context = {},
337
+ updateContext,
338
+ emitEvents = [],
339
+ componentSchema = {},
340
+ forContext: parentForItems = {},
341
+ } = props;
342
+
343
+ const _context = {
344
+ scopeContext,
345
+ forContext: parentForItems,
346
+ codeContext,
347
+ dataContext: context,
305
348
  };
306
349
 
350
+ const isInComposite = !!codeContext;
351
+ // 判断 widgets 是从 page 来的,还是组件来的
352
+ const widgetsData = !isInComposite
353
+ ? $page.widgets[compId]
354
+ : codeContext.$WEAPPS_COMP.widgets[compId];
355
+
356
+ if (!xProps) {
357
+ return (
358
+ <>
359
+ {getComponentChildren(componentSchema, {
360
+ ..._context,
361
+ virtualFields,
362
+ updateContext,
363
+ })}
364
+ </>
365
+ );
366
+ }
367
+
368
+ const { commonStyle = {}, sourceKey, dataBinds, classNameList = [] } = xProps;
369
+ const Field = virtualFields[sourceKey];
370
+
371
+ // For循环渲染
372
+ let forList = getForList(compId, dataBinds, parentForItems, context);
373
+
374
+ if (forList) {
375
+ return forList
376
+ .map((item, index) => {
377
+ const forItemsIndexes = (parentForItems['forIndexes'] || []).concat(
378
+ index
379
+ );
380
+ const forItems = {
381
+ ...parentForItems,
382
+ [compId]: item,
383
+ forIndexes: forItemsIndexes,
384
+ };
385
+ const {
386
+ fieldData: forItemData,
387
+ finalStyle: forItemStyle,
388
+ finalClassNameList: forItemClassNameList,
389
+ } = getBindData({
390
+ widgetData: widgetsData,
391
+ forItems,
392
+ scopeContext,
393
+ codeContext,
394
+ commonStyle,
395
+ classNameList,
396
+ });
397
+ if (!checkVisible(forItemData)) {
398
+ return null;
399
+ }
400
+
401
+ const slotMap = generateSlotMap(
402
+ generateSlotMetaMap(
403
+ componentSchema,
404
+ {
405
+ ..._context,
406
+ forContext: forItems,
407
+ virtualFields,
408
+ updateContext,
409
+ },
410
+ {
411
+ renderSlot,
412
+ }
413
+ )
414
+ );
415
+
416
+ return (
417
+ <ForContext.Provider key={index} value={forItems}>
418
+ <FieldWrapper
419
+ Field={Field}
420
+ componentSchema={componentSchema}
421
+ context={{
422
+ ..._context,
423
+ widgetsData,
424
+ forContext: forItems,
425
+ forIndexes: forItemsIndexes,
426
+ }}
427
+ id={compId}
428
+ updateContext={updateContext}
429
+ data={{
430
+ ...forItemData,
431
+ ...slotMap,
432
+ }}
433
+ {...getSafeComponentProps({
434
+ style: forItemStyle,
435
+ classNameList: forItemClassNameList,
436
+ })}
437
+ events={emitEvents}
438
+ compositeParent={codeContext}
439
+ >
440
+ {getComponentChildren(componentSchema, {
441
+ ..._context,
442
+ forContext: forItems,
443
+ virtualFields,
444
+ updateContext,
445
+ })}
446
+ </FieldWrapper>
447
+ </ForContext.Provider>
448
+ );
449
+ })
450
+ .filter((item) => !!item);
451
+ }
452
+
453
+ // 修正 forIndexes
454
+ const forIndexes = getForIndexes(parentForItems, widgetsData);
455
+
456
+ // 单节点渲染
457
+ const { fieldData, finalClassNameList, finalStyle } = getBindData({
458
+ widgetData: widgetsData,
459
+ forItems: parentForItems,
460
+ scopeContext,
461
+ codeContext,
462
+ commonStyle,
463
+ classNameList,
464
+ });
465
+
307
466
  // false 或空字符串时
308
467
  if (!checkVisible(fieldData)) {
309
468
  return null;
@@ -314,7 +473,7 @@ export const CompRenderer = observer(function (props) {
314
473
  generateSlotMetaMap(
315
474
  componentSchema,
316
475
  {
317
- ...context,
476
+ ..._context,
318
477
  virtualFields,
319
478
  updateContext,
320
479
  },
@@ -324,106 +483,37 @@ export const CompRenderer = observer(function (props) {
324
483
  )
325
484
  );
326
485
 
327
- // 防止渲染时 data 的 style 与实际的 style 冲突
328
- delete fieldData.style;
329
-
330
- // 修正 forIndexes
331
- const forIndexes = getForIndexes(parentForItems, widgetsData);
332
-
333
- // 获取 Element Ref
334
- const currentWidget = Array.isArray(widgetsData)
335
- ? get(widgetsData, forIndexes)
336
- : widgetsData;
337
- const domRef = setGetDomApi(currentWidget, props);
338
-
339
- const componentProps = getSafeComponentProps({
340
- style: finalStyle,
341
- classNameList: finalClassNameList,
342
- staticResourceAttribute,
343
- });
344
-
345
- // 判断为容器组件,则增加一个onDataChange事件
346
- if (
347
- componentSchema?.compConfig?.isDataContainer &&
348
- !emitEvents?.includes('onDataChange')
349
- ) {
350
- emitEvents.push('onDataChange');
351
- }
352
-
353
486
  return (
354
- <Field
487
+ <FieldWrapper
488
+ key={key}
489
+ Field={Field}
490
+ componentSchema={componentSchema}
491
+ context={{
492
+ ..._context,
493
+ forIndexes: forIndexes,
494
+ widgetsData,
495
+ }}
496
+ id={compId}
497
+ updateContext={updateContext}
355
498
  data={{
356
499
  ...fieldData,
357
500
  ...slotMap,
358
- _selectableBlockEvents: _selectableBlockEventsWithItem,
359
501
  }}
360
- id={compId}
361
- {...componentProps}
362
- emit={emitWithForItems}
502
+ {...getSafeComponentProps({
503
+ style: finalStyle,
504
+ classNameList: finalClassNameList,
505
+ })}
363
506
  events={emitEvents}
364
507
  compositeParent={codeContext}
365
- forIndexes={forIndexes}
366
- $node={currentWidget}
367
- domRef={domRef}
368
508
  >
369
- {props.children}
370
- </Field>
509
+ {getComponentChildren(componentSchema, {
510
+ ..._context,
511
+ virtualFields,
512
+ updateContext,
513
+ })}
514
+ </FieldWrapper>
371
515
  );
372
-
373
- // TODO: 需要不断移除 dataBinds(style/classList)
374
- function getBindData(forItems, scopeContext) {
375
- // bindData
376
- let wData = widgetsData;
377
- if (Array.isArray(wData)) {
378
- wData =
379
- forItems.forIndexes === void 0 || wData.length === 0
380
- ? {}
381
- : get(wData, getForIndexes(forItems, wData));
382
- }
383
- wData = wData || {};
384
- const fieldData = { ...wData };
385
-
386
- // 再次计算 scope value
387
- for (let key in fieldData) {
388
- if (Object.prototype.hasOwnProperty.call(fieldData, key)) {
389
- const value = fieldData[key];
390
- if (value && value.__type === 'scopedValue') {
391
- try {
392
- fieldData[key] = value.getValue(scopeContext);
393
- } catch (e) {
394
- console.warn(`Error computing data bind '${key}' error:`, e);
395
- fieldData[key] = '';
396
- }
397
- }
398
- }
399
- }
400
-
401
- // bindStyle
402
- let bindStyle = fieldData.style || {};
403
- // 复合组件第一层需要将最外层样式 style 挂到节点上
404
- let cssStyle = commonStyle;
405
- if (isInComposite && wData && !wData.parent) {
406
- cssStyle = {
407
- ...cssStyle,
408
- ...(codeContext.$WEAPPS_COMP.props?.style || {}),
409
- };
410
- bindStyle = {
411
- ...bindStyle,
412
- ...(codeContext.$WEAPPS_COMP.props?.style || {}),
413
- };
414
- }
415
- const finalStyle = getFinalStyle(cssStyle, bindStyle);
416
-
417
- // bindClassList
418
- const bindClassList = fieldData.classList || [];
419
- const finalClassNameList = getFinalClassNameList(
420
- classNameList,
421
- bindClassList
422
- );
423
-
424
- return { fieldData, finalStyle, finalClassNameList };
425
- }
426
- });
516
+ }
427
517
 
428
518
  export function getFinalStyle(
429
519
  commonStyle = {},
@@ -1,17 +1,117 @@
1
1
  import * as React from 'react';
2
- import { useRef } from 'react';
3
2
  import * as _ from 'lodash';
4
- import { CompRenderer, ForContext } from './FieldMiddleware/renderer';
3
+ import { ForContext, getComponentRenderList } from './FieldMiddleware/renderer';
5
4
  import { isScopeSlot } from '../utils/index';
5
+ import { observer } from 'mobx-react-lite';
6
6
 
7
- function getComponentChildren(component) {
7
+ export function getComponentChildren(component, context = {}) {
8
8
  const { properties } = component;
9
9
  if (!properties) {
10
10
  return [];
11
11
  }
12
- return Object.values(properties).sort(
12
+ const list = Object.values(properties).sort(
13
13
  (a, b) => (a['x-index'] || 0) - (b['x-index'] || 0)
14
14
  );
15
+ const {
16
+ virtualFields,
17
+ codeContext,
18
+ scopeContext,
19
+ forContext,
20
+ injectContext = {},
21
+ dataContext,
22
+ updateContext,
23
+ } = context;
24
+
25
+ return list.map((schema) => {
26
+ return getRenderList({
27
+ key: schema.key,
28
+ componentSchema: schema,
29
+ rootNode: false,
30
+ renderSlot: false,
31
+ virtualFields,
32
+ codeContext,
33
+ scopeContext,
34
+ forContext,
35
+ injectContext,
36
+ context: dataContext,
37
+ updateContext,
38
+ });
39
+ });
40
+ }
41
+
42
+ function getRenderList(props) {
43
+ const {
44
+ key = '',
45
+ className,
46
+ virtualFields,
47
+ componentSchema,
48
+ renderSlot,
49
+ rootNode = true,
50
+ codeContext,
51
+ scopeContext = {},
52
+ context = {},
53
+ updateContext,
54
+ forContext = {},
55
+ } = props;
56
+
57
+ const { 'x-props': xProps, properties = {} } = componentSchema;
58
+
59
+ // 判断是否为 slot
60
+ const isSlot = !xProps;
61
+ if (isSlot && !(renderSlot || rootNode)) {
62
+ return null;
63
+ }
64
+
65
+ // const preClassName = useRef();
66
+
67
+ // wrapperClass
68
+ const containerEl = Object.values(properties)[0];
69
+ if (containerEl && containerEl['x-props'] && className) {
70
+ let { classNameList = [] } = containerEl['x-props'];
71
+
72
+ // 先替换掉先前计算出来的className部分
73
+ // if (preClassName.current) {
74
+ // if (preClassName.current !== className) {
75
+ // classNameList = classNameList.filter(
76
+ // (clsName) => clsName !== preClassName.current
77
+ // );
78
+ // preClassName.current = className;
79
+ // }
80
+ // } else {
81
+ // preClassName.current = className;
82
+ // }
83
+
84
+ containerEl['x-props'].classNameList = Array.from(
85
+ new Set([className, ...classNameList])
86
+ );
87
+ }
88
+
89
+ if (xProps && xProps.sourceKey) {
90
+ const { sourceKey } = xProps;
91
+ const Field = virtualFields[sourceKey];
92
+ if (!Field) {
93
+ return (
94
+ <div style={{ color: 'red' }}>
95
+ 组件<em>{sourceKey}</em>未找到
96
+ </div>
97
+ );
98
+ }
99
+ }
100
+
101
+ return getComponentRenderList({
102
+ key,
103
+ componentSchema,
104
+ id: componentSchema.key,
105
+ xProps,
106
+ emitEvents: componentSchema.emitEvents || [],
107
+ virtualFields,
108
+ renderSlot,
109
+ codeContext,
110
+ scopeContext,
111
+ forContext,
112
+ context,
113
+ updateContext,
114
+ });
15
115
  }
16
116
 
17
117
  export function generateSlotMetaMap(componentSchema, context, options = {}) {
@@ -36,14 +136,10 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
36
136
  node: isHOC
37
137
  ? (props) => {
38
138
  let clonedScopeContext = _.cloneDeep(scopeContext);
39
- _.set(
40
- clonedScopeContext,
41
- `${componentSchema.key}.${child.key}`,
42
- props
43
- );
139
+ _.set(clonedScopeContext, `${componentSchema.key}.${key}`, props);
44
140
  return (
45
141
  <AppRender
46
- key={child.key}
142
+ key={key}
47
143
  componentSchema={child}
48
144
  renderSlot={options?.renderSlot}
49
145
  virtualFields={virtualFields}
@@ -58,7 +154,7 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
58
154
  return (
59
155
  <ForContext.Provider value={forContext}>
60
156
  <AppRender
61
- key={child.key}
157
+ key={key}
62
158
  componentSchema={child}
63
159
  renderSlot={options?.renderSlot}
64
160
  virtualFields={virtualFields}
@@ -76,89 +172,10 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
76
172
  return slots;
77
173
  }
78
174
 
79
- export function AppRender(props) {
80
- const {
81
- className,
82
- virtualFields,
83
- componentSchema,
84
- renderSlot,
85
- rootNode = true,
86
- codeContext,
87
- scopeContext = {},
88
- context = {},
89
- updateContext,
90
- } = props;
91
-
92
- const { 'x-props': xProps, properties = {} } = componentSchema;
93
-
94
- // 判断是否为 slot
95
- const isSlot = !xProps;
96
- if (isSlot && !(renderSlot || rootNode)) {
97
- return null;
98
- }
99
-
100
- const preClassName = useRef();
101
-
102
- // wrapperClass
103
- const containerEl = Object.values(properties)[0];
104
- if (containerEl && containerEl['x-props'] && className) {
105
- let { classNameList = [] } = containerEl['x-props'];
106
-
107
- // 先替换掉先前计算出来的className部分
108
- if (preClassName.current) {
109
- if (preClassName.current !== className) {
110
- classNameList = classNameList.filter(
111
- (clsName) => clsName !== preClassName.current
112
- );
113
- preClassName.current = className;
114
- }
115
- } else {
116
- preClassName.current = className;
117
- }
118
-
119
- containerEl['x-props'].classNameList = [className, ...classNameList];
120
- }
121
-
122
- if (xProps && xProps.sourceKey) {
123
- const { sourceKey } = xProps;
124
- const Field = virtualFields[sourceKey];
125
- if (!Field) {
126
- return (
127
- <div style={{ color: 'red' }}>
128
- 组件<em>{sourceKey}</em>未找到
129
- </div>
130
- );
131
- }
132
- }
133
-
134
- const children = getComponentChildren(componentSchema);
135
-
136
- return (
137
- <CompRenderer
138
- id={componentSchema.key}
139
- xProps={xProps}
140
- emitEvents={componentSchema.emitEvents || []}
141
- componentSchema={componentSchema}
142
- virtualFields={virtualFields}
143
- renderSlot={renderSlot}
144
- codeContext={codeContext}
145
- scopeContext={scopeContext}
146
- context={context}
147
- updateContext={updateContext}
148
- >
149
- {children.map((comp) => (
150
- <AppRender
151
- key={comp.key}
152
- componentSchema={comp}
153
- rootNode={false}
154
- renderSlot={false}
155
- virtualFields={virtualFields}
156
- codeContext={codeContext}
157
- scopeContext={scopeContext}
158
- context={context}
159
- updateContext={updateContext}
160
- />
161
- ))}
162
- </CompRenderer>
163
- );
164
- }
175
+ export const AppRender = observer(function (props) {
176
+ return getRenderList({
177
+ ...props,
178
+ forContext: React.useContext(ForContext),
179
+ injectContext: {},
180
+ });
181
+ });
@@ -77,7 +77,7 @@ export function resolveComponentProps(props, isPlainProps) {
77
77
  ...props,
78
78
  };
79
79
  }
80
- const { data = {}, events = [], ...restProps } = props;
80
+ const { data = {}, events = [], $node, ...restProps } = props;
81
81
  const customProps = { ...data };
82
82
  const builtinProps = [
83
83
  // react 保留字
@@ -78,32 +78,13 @@ initLifeCycle({
78
78
  export default function App() {
79
79
  // 检查权限
80
80
  const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);
81
- const context = React.useRef(observable({})).current;
81
+ const dataContextRef = React.useRef(observable({}))
82
+ const context = dataContextRef.current;
82
83
  const containerRef = React.useRef(null);
83
84
  const microApp = React.useRef(null);
84
85
  const pureSrc = '<%= pageSource %>';
85
86
  const isPure = !!pureSrc;
86
87
 
87
- /**
88
- * 更新数据容器的上下文的方法
89
- * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
90
- * 当组件卸载时,传过来的data为undefined即可
91
- * {
92
- * id1: [{...}],
93
- * id2: {...},
94
- * id3: undefined,
95
- * id4: null,
96
- * ...
97
- * }
98
- * @param id
99
- * @param data
100
- */
101
- const updateContext = (id, data) => {
102
- if (id) {
103
- context[id] = { data };
104
- }
105
- }
106
-
107
88
  React.useEffect(() => {
108
89
  checkAuth(app, app.id, '<%= pageName %>').then((checkAuthResult) => {
109
90
  setWeDaHasLogin(checkAuthResult)
@@ -114,6 +95,7 @@ export default function App() {
114
95
  id: '<%= pageName %>',
115
96
  state: observable(initPageState),
116
97
  computed: createComputed(computed),
98
+ // _context: context,
117
99
  handler,
118
100
  });
119
101
 
@@ -133,10 +115,10 @@ export default function App() {
133
115
  }, []);
134
116
 
135
117
  React.useEffect(() => {
136
- $page.widgets = createWidgets(widgetsContext, dataBinds, {}, context);
118
+ $page.widgets = createWidgets(widgetsContext, dataBinds, {}, dataContextRef.current);
137
119
  // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds
138
120
  retryDataBinds();
139
- }, [context]);
121
+ }, [dataContextRef.current]);
140
122
 
141
123
  // Web 环境页面级别生命周期
142
124
  if (!process.env.isMiniprogram) {
@@ -178,8 +160,27 @@ export default function App() {
178
160
  <AppRender pageListenerInstances={pageListenerInstances}
179
161
  virtualFields={virtualFields}
180
162
  componentSchema={componentSchema}
181
- context={context}
182
- updateContext={updateContext}
163
+ context={dataContextRef.current}
164
+ /**
165
+ * 更新数据容器的上下文的方法
166
+ * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
167
+ * 当组件卸载时,传过来的data为undefined即可
168
+ * {
169
+ * id1: [{...}],
170
+ * id2: {...},
171
+ * id3: undefined,
172
+ * id4: null,
173
+ * ...
174
+ * }
175
+ * @param id
176
+ * @param data
177
+ */
178
+ updateContext={(id, data) => {
179
+ if (id) {
180
+ dataContextRef.current[id] = { data };
181
+ // console.log('111', context[id])
182
+ }
183
+ }}
183
184
  />
184
185
  )}
185
186
  </div>