airx 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ export interface AirxElement<P = any> {
15
15
  props: Props & P;
16
16
  [symbol.airxElementSymbol]: true;
17
17
  }
18
- export type AirxChildren = null | string | number | boolean | undefined | AirxElement | Array<AirxChildren>;
18
+ export type AirxChildren = null | string | number | boolean | undefined | AirxElement | Array<AirxChildren> | AirxComponentRender;
19
19
  /**
20
20
  * 函数式组件接收自己的 props,并返回一个 AirxElement
21
21
  */
@@ -84,11 +84,18 @@ const airxElementSymbol = Symbol('airx-element');
84
84
  */
85
85
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
86
  function createElement(type, props, ...children) {
87
+ const localChildren = [];
88
+ if (children.length > 0) {
89
+ localChildren.push(...children);
90
+ }
91
+ else if (props && props.children) {
92
+ localChildren.push(props.children);
93
+ }
87
94
  return {
88
95
  type,
89
96
  props: {
90
97
  ...props,
91
- children
98
+ children: localChildren
92
99
  },
93
100
  [airxElementSymbol]: true
94
101
  };
@@ -384,10 +391,16 @@ function reconcileChildren(appContext, parentInstance, childrenElementArray) {
384
391
  if ('ref' in instance.memoProps) {
385
392
  context.onMounted(() => {
386
393
  const ref = instance.memoProps.ref;
387
- // 如果组件有自己的 dom 并且 ref 为 state
388
- if (instance.domRef && isState(ref)) {
389
- ref.set(instance.domRef);
390
- return () => ref.set(undefined);
394
+ // 如果组件有自己的 dom
395
+ if (instance.domRef) {
396
+ if (isState(ref)) {
397
+ ref.set(instance.domRef);
398
+ return () => ref.set(undefined);
399
+ }
400
+ if (typeof ref === 'function') {
401
+ ref(instance.domRef);
402
+ return () => ref(undefined);
403
+ }
391
404
  }
392
405
  });
393
406
  }
@@ -452,22 +465,7 @@ function performUnitOfWork(pluginContext, instance, onUpdateRequire) {
452
465
  }
453
466
  // airx 组件
454
467
  if (typeof element?.type === 'function') {
455
- if (instance.signalWatcher == null) {
456
- // Watch 是惰性的,只有当 Signal 被读取时才会触发 --!
457
- const signalWatcher = createWatch(async () => {
458
- instance.needReRender = true;
459
- onUpdateRequire?.(instance);
460
- queueMicrotask(() => {
461
- signalWatcher.watch();
462
- const paddings = signalWatcher.getPending();
463
- for (const padding of paddings)
464
- padding.get();
465
- });
466
- });
467
- instance.signalWatcher = signalWatcher;
468
- instance.context.addDisposer(() => signalWatcher.unwatch());
469
- }
470
- if (instance.childrenRender == null) {
468
+ if (instance.componentReturnValue == null) {
471
469
  const component = element.type;
472
470
  const beforeContext = globalContext.current;
473
471
  globalContext.current = instance.context.getSafeContext();
@@ -478,32 +476,58 @@ function performUnitOfWork(pluginContext, instance, onUpdateRequire) {
478
476
  catch (error) {
479
477
  componentReturnValue = createErrorRender(error);
480
478
  }
481
- if (typeof componentReturnValue !== 'function') {
482
- const error = new Error('Component must return a render function');
483
- componentReturnValue = createErrorRender(error.message);
484
- }
485
479
  // restore context
486
480
  globalContext.current = beforeContext;
487
- instance.childrenRender = componentReturnValue;
488
- const childrenComputed = createComputed(() => {
489
- try {
490
- return instance.childrenRender();
491
- }
492
- catch (error) {
493
- return createErrorRender(error)();
481
+ instance.componentReturnValue = componentReturnValue;
482
+ // static function component
483
+ if (isValidElement(componentReturnValue)) {
484
+ const elements = childrenAsElements(componentReturnValue);
485
+ reconcileChildren(pluginContext, instance, elements);
486
+ }
487
+ // reaction function component
488
+ if (typeof componentReturnValue === 'function') {
489
+ if (instance.signalWatcher == null) {
490
+ // Watch 是惰性的,只有当 Signal 被读取时才会触发 --!
491
+ const signalWatcher = createWatch(async () => {
492
+ instance.needReRender = true;
493
+ onUpdateRequire?.(instance);
494
+ queueMicrotask(() => {
495
+ signalWatcher.watch();
496
+ const paddings = signalWatcher.getPending();
497
+ for (const padding of paddings)
498
+ padding.get();
499
+ });
500
+ });
501
+ instance.signalWatcher = signalWatcher;
502
+ instance.context.addDisposer(() => signalWatcher.unwatch());
494
503
  }
495
- });
496
- instance.signalWatcher.watch(childrenComputed);
497
- const children = childrenComputed.get();
498
- reconcileChildren(pluginContext, instance, childrenAsElements(children));
504
+ const childrenComputed = createComputed(() => {
505
+ try {
506
+ if (typeof componentReturnValue === 'function') {
507
+ return componentReturnValue();
508
+ }
509
+ }
510
+ catch (error) {
511
+ return createErrorRender(error)();
512
+ }
513
+ });
514
+ instance.signalWatcher.watch(childrenComputed);
515
+ const children = childrenComputed.get();
516
+ reconcileChildren(pluginContext, instance, childrenAsElements(children));
517
+ }
499
518
  }
500
519
  if (instance.needReRender) {
501
520
  let children;
502
521
  try {
503
- // 如果是由于父组件导致的子组件渲染
504
- // 直接使用 childrenComputed.get() 将读取到缓存值
505
- // 因此这里使用 childrenRender 来更新 children 的值
506
- children = instance.childrenRender();
522
+ if (isValidElement(instance.componentReturnValue)) {
523
+ children = instance.componentReturnValue;
524
+ }
525
+ else {
526
+ // 如果是由于父组件导致的子组件渲染
527
+ // 直接使用 childrenComputed.get() 将读取到缓存值
528
+ // 因此这里使用 childrenRender 来更新 children 的值
529
+ children = instance.componentReturnValue();
530
+ }
507
531
  }
508
532
  catch (error) {
509
533
  children = createErrorRender(error)();