@tarojs/runtime 3.7.0-alpha.0 → 3.7.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/runtime.cjs.d.ts +780 -0
  2. package/dist/runtime.cjs.js +4582 -0
  3. package/dist/runtime.esm.d.ts +153 -76
  4. package/dist/runtime.esm.js +197 -74
  5. package/dist/runtime.esm.js.map +1 -1
  6. package/dist/runtime.h5.d.ts +780 -0
  7. package/dist/runtime.h5.js +3348 -0
  8. package/package.json +11 -6
  9. package/dist/bom/URL.d.ts +0 -61
  10. package/dist/bom/URLSearchParams.d.ts +0 -14
  11. package/dist/bom/document.d.ts +0 -2
  12. package/dist/bom/getComputedStyle.d.ts +0 -3
  13. package/dist/bom/history.d.ts +0 -29
  14. package/dist/bom/location.d.ts +0 -36
  15. package/dist/bom/navigator.d.ts +0 -1
  16. package/dist/bom/raf.d.ts +0 -5
  17. package/dist/bom/window.d.ts +0 -4
  18. package/dist/constants/index.d.ts +0 -58
  19. package/dist/current.d.ts +0 -19
  20. package/dist/dom/anchor-element.d.ts +0 -13
  21. package/dist/dom/class-list.d.ts +0 -14
  22. package/dist/dom/custom-wrapper.d.ts +0 -4
  23. package/dist/dom/document.d.ts +0 -20
  24. package/dist/dom/element.d.ts +0 -38
  25. package/dist/dom/event-source.d.ts +0 -7
  26. package/dist/dom/event-target.d.ts +0 -7
  27. package/dist/dom/event.d.ts +0 -23
  28. package/dist/dom/form.d.ts +0 -7
  29. package/dist/dom/node.d.ts +0 -75
  30. package/dist/dom/node_types.d.ts +0 -10
  31. package/dist/dom/root.d.ts +0 -15
  32. package/dist/dom/style.d.ts +0 -14
  33. package/dist/dom/style_properties.d.ts +0 -3
  34. package/dist/dom/svg.d.ts +0 -3
  35. package/dist/dom/text.d.ts +0 -14
  36. package/dist/dom/tree.d.ts +0 -4
  37. package/dist/dom-external/element.d.ts +0 -3
  38. package/dist/dom-external/index.d.ts +0 -1
  39. package/dist/dom-external/inner-html/html.d.ts +0 -2
  40. package/dist/dom-external/inner-html/parser.d.ts +0 -25
  41. package/dist/dom-external/inner-html/scaner.d.ts +0 -30
  42. package/dist/dom-external/inner-html/style.d.ts +0 -27
  43. package/dist/dom-external/inner-html/tags.d.ts +0 -8
  44. package/dist/dom-external/inner-html/utils.d.ts +0 -1
  45. package/dist/dom-external/mutation-observer/implements.d.ts +0 -52
  46. package/dist/dom-external/mutation-observer/index.d.ts +0 -13
  47. package/dist/dom-external/mutation-observer/record.d.ts +0 -24
  48. package/dist/dom-external/node.d.ts +0 -11
  49. package/dist/dsl/common.d.ts +0 -16
  50. package/dist/dsl/instance.d.ts +0 -87
  51. package/dist/emitter/emitter.d.ts +0 -4
  52. package/dist/env.d.ts +0 -7
  53. package/dist/hydrate.d.ts +0 -10
  54. package/dist/index.d.ts +0 -30
  55. package/dist/interface/element.d.ts +0 -4
  56. package/dist/interface/event-target.d.ts +0 -10
  57. package/dist/interface/event.d.ts +0 -15
  58. package/dist/interface/hydrate.d.ts +0 -30
  59. package/dist/interface/index.d.ts +0 -7
  60. package/dist/interface/node.d.ts +0 -7
  61. package/dist/interface/options.d.ts +0 -16
  62. package/dist/interface/utils.d.ts +0 -2
  63. package/dist/next-tick.d.ts +0 -2
  64. package/dist/options.d.ts +0 -2
  65. package/dist/perf.d.ts +0 -7
  66. package/dist/utils/cache.d.ts +0 -12
  67. package/dist/utils/index.d.ts +0 -23
@@ -2,6 +2,8 @@ import { noop, isFunction, getComponentsAlias as getComponentsAlias$1, internalC
2
2
  export { Events, hooks } from '@tarojs/shared';
3
3
 
4
4
  const PROPERTY_THRESHOLD = 2046;
5
+ const TARO_RUNTIME = 'Taro runtime';
6
+ const HOOKS_APP_ID = 'taro-app';
5
7
  const SET_DATA = '小程序 setData';
6
8
  const PAGE_INIT = '页面初始化';
7
9
  const ROOT_STR = 'root';
@@ -34,6 +36,8 @@ const CONFIRM = 'confirm';
34
36
  const TIME_STAMP = 'timeStamp';
35
37
  const KEY_CODE = 'keyCode';
36
38
  const TOUCHMOVE = 'touchmove';
39
+ const DATE = 'Date';
40
+ const SET_TIMEOUT = 'setTimeout';
37
41
  const CATCHMOVE = 'catchMove';
38
42
  const CATCH_VIEW = 'catch-view';
39
43
  const COMMENT = 'comment';
@@ -283,46 +287,90 @@ function getComponentsAlias() {
283
287
  return componentsAlias$1;
284
288
  }
285
289
 
286
- class ClassList extends Set {
290
+ class ClassList {
287
291
  constructor(className, el) {
288
- super();
289
- className.trim().split(/\s+/).forEach(super.add.bind(this));
292
+ this.tokenList = [];
290
293
  this.el = el;
294
+ className.trim().split(/\s+/).forEach(token => this.tokenList.push(token));
291
295
  }
292
296
  get value() {
293
- return [...this].filter(v => v !== '').join(' ');
294
- }
295
- add(s) {
296
- super.add(s);
297
- this._update();
298
- return this;
297
+ return this.toString();
299
298
  }
300
299
  get length() {
301
- return this.size;
300
+ return this.tokenList.length;
301
+ }
302
+ add() {
303
+ let index = 0;
304
+ let updated = false;
305
+ const tokens = arguments;
306
+ const length = tokens.length;
307
+ const tokenList = this.tokenList;
308
+ do {
309
+ const token = tokens[index];
310
+ if (this.checkTokenIsValid(token) && !~tokenList.indexOf(token)) {
311
+ tokenList.push(token);
312
+ updated = true;
313
+ }
314
+ } while (++index < length);
315
+ if (updated) {
316
+ this._update();
317
+ }
318
+ }
319
+ remove() {
320
+ let i = 0;
321
+ let updated = false;
322
+ const tokens = arguments;
323
+ const length = tokens.length;
324
+ const tokenList = this.tokenList;
325
+ do {
326
+ const token = tokens[i] + '';
327
+ if (!this.checkTokenIsValid(token))
328
+ continue;
329
+ const index = tokenList.indexOf(token);
330
+ if (~tokenList.indexOf(token)) {
331
+ tokenList.splice(index, 1);
332
+ updated = true;
333
+ }
334
+ } while (++i < length);
335
+ if (updated) {
336
+ this._update();
337
+ }
302
338
  }
303
- remove(s) {
304
- super.delete(s);
305
- this._update();
339
+ contains(token) {
340
+ if (!this.checkTokenIsValid(token))
341
+ return false;
342
+ return !!~this.tokenList.indexOf(token);
306
343
  }
307
- toggle(s) {
308
- if (super.has(s)) {
309
- super.delete(s);
344
+ toggle(token, force) {
345
+ const result = this.contains(token);
346
+ const method = result ? force !== true && 'remove' : force !== false && 'add';
347
+ if (method) {
348
+ // @ts-ignore
349
+ this[method](token);
350
+ }
351
+ if (force === true || force === false) {
352
+ return force;
310
353
  }
311
354
  else {
312
- super.add(s);
355
+ return !result;
313
356
  }
314
- this._update();
315
357
  }
316
- replace(s1, s2) {
317
- super.delete(s1);
318
- super.add(s2);
319
- this._update();
320
- }
321
- contains(s) {
322
- return super.has(s);
358
+ replace(token, replacement_token) {
359
+ if (!this.checkTokenIsValid(token) || !this.checkTokenIsValid(replacement_token))
360
+ return;
361
+ const index = this.tokenList.indexOf(token);
362
+ if (~index) {
363
+ this.tokenList.splice(index, 1, replacement_token);
364
+ this._update();
365
+ }
323
366
  }
324
367
  toString() {
325
- return this.value;
368
+ return this.tokenList.filter(v => v !== '').join(' ');
369
+ }
370
+ checkTokenIsValid(token) {
371
+ if (token === '' || /\s/.test(token))
372
+ return false;
373
+ return true;
326
374
  }
327
375
  _update() {
328
376
  this.el.className = this.value;
@@ -359,6 +407,7 @@ let componentsAlias;
359
407
  * it's a vnode traverser and modifier: that's exactly what Taro's doing in here.
360
408
  */
361
409
  function hydrate(node) {
410
+ var _a;
362
411
  if (!componentsAlias) {
363
412
  // 初始化 componentsAlias
364
413
  componentsAlias = getComponentsAlias();
@@ -371,7 +420,7 @@ function hydrate(node) {
371
420
  if (isText(node)) {
372
421
  return {
373
422
  ["v" /* Shortcuts.Text */]: node.nodeValue,
374
- ["nn" /* Shortcuts.NodeName */]: componentsAlias[nodeName]._num
423
+ ["nn" /* Shortcuts.NodeName */]: ((_a = componentsAlias[nodeName]) === null || _a === void 0 ? void 0 : _a._num) || '8'
375
424
  };
376
425
  }
377
426
  const data = {
@@ -529,6 +578,18 @@ class TaroNode extends TaroEventTarget {
529
578
  value: isClean ? cleanChildNodes : rerenderChildNodes
530
579
  });
531
580
  }
581
+ updateSingleChild(index) {
582
+ this.childNodes.forEach((child, childIndex) => {
583
+ if (isComment(child))
584
+ return;
585
+ if (index && childIndex < index)
586
+ return;
587
+ this.enqueueUpdate({
588
+ path: child._path,
589
+ value: this.hydrate(child)
590
+ });
591
+ });
592
+ }
532
593
  get _root() {
533
594
  var _a;
534
595
  return ((_a = this.parentNode) === null || _a === void 0 ? void 0 : _a._root) || null;
@@ -620,22 +681,24 @@ class TaroNode extends TaroEventTarget {
620
681
  // - cleanRef: false (No need to clean eventSource, because newChild is about to be inserted)
621
682
  // - update: true (Need to update parent.childNodes, because parent.childNodes is reordered)
622
683
  newChild.remove({ cleanRef: false });
684
+ let index = 0;
623
685
  // Data structure
624
686
  newChild.parentNode = this;
625
687
  if (refChild) {
626
688
  // insertBefore & replaceChild
627
- const index = this.findIndex(refChild);
689
+ index = this.findIndex(refChild);
628
690
  this.childNodes.splice(index, 0, newChild);
629
691
  }
630
692
  else {
631
693
  // appendChild
632
694
  this.childNodes.push(newChild);
633
695
  }
696
+ const childNodesLength = this.childNodes.length;
634
697
  // Serialization
635
698
  if (this._root) {
636
699
  if (!refChild) {
637
700
  // appendChild
638
- const isOnlyChild = this.childNodes.length === 1;
701
+ const isOnlyChild = childNodesLength === 1;
639
702
  if (isOnlyChild) {
640
703
  this.updateChildNodes();
641
704
  }
@@ -654,8 +717,26 @@ class TaroNode extends TaroEventTarget {
654
717
  });
655
718
  }
656
719
  else {
657
- // insertBefore
658
- this.updateChildNodes();
720
+ // insertBefore 有两种更新模式
721
+ // 比方说有 A B C 三个节点,现在要在 C 前插入 D
722
+ // 1. 插入 D,然后更新整个父节点的 childNodes 数组
723
+ // setData({ cn: [A, B, D, C] })
724
+ // 2. 插入 D,然后更新 D 以及 D 之后每个节点的数据
725
+ // setData ({
726
+ // cn.[2]: D,
727
+ // cn.[3]: C,
728
+ // })
729
+ // 由于微信解析 ’cn.[2]‘ 这些路径的时候也需要消耗时间,
730
+ // 所以根据 insertBefore 插入的位置来做不同的处理
731
+ const mark = childNodesLength * 2 / 3;
732
+ if (mark > index) {
733
+ // 如果 insertBefore 的位置在 childNodes 的 2/3 前,则为了避免解析路径消耗过多的时间,采用第一种方式
734
+ this.updateChildNodes();
735
+ }
736
+ else {
737
+ // 如果 insertBefore 的位置在 childNodes 的 2/3 之后,则采用第二种方式,避免 childNodes 的全量更新
738
+ this.updateSingleChild(index);
739
+ }
659
740
  }
660
741
  }
661
742
  MutationObserver.record({
@@ -803,7 +884,8 @@ const styleProperties = [
803
884
  'widows',
804
885
  'width',
805
886
  'zIndex',
806
- 'pointerEvents'
887
+ 'pointerEvents',
888
+ 'aspectRatio'
807
889
  /** 非常用 style */
808
890
  // 'azimuth',
809
891
  // 'backfaceVisibility',
@@ -971,10 +1053,12 @@ function setStyle(newVal, styleKey) {
971
1053
  }
972
1054
  !this._pending && enqueueUpdate(this);
973
1055
  }
974
- function initStyle(ctor) {
1056
+ function initStyle(ctor, styleProperties) {
975
1057
  const properties = {};
976
1058
  for (let i = 0; i < styleProperties.length; i++) {
977
1059
  const styleKey = styleProperties[i];
1060
+ if (ctor[styleKey])
1061
+ return;
978
1062
  properties[styleKey] = {
979
1063
  get() {
980
1064
  const val = this._value[styleKey];
@@ -1085,7 +1169,17 @@ class Style {
1085
1169
  return value;
1086
1170
  }
1087
1171
  }
1088
- initStyle(Style);
1172
+ initStyle(Style, styleProperties);
1173
+ hooks.tap('injectNewStyleProperties', (newStyleProperties) => {
1174
+ if (isArray(newStyleProperties)) {
1175
+ initStyle(Style, newStyleProperties);
1176
+ }
1177
+ else {
1178
+ if (typeof newStyleProperties !== 'string')
1179
+ return;
1180
+ initStyle(Style, [newStyleProperties]);
1181
+ }
1182
+ });
1089
1183
 
1090
1184
  function returnTrue() {
1091
1185
  return true;
@@ -1104,7 +1198,9 @@ function treeToArray(root, predict) {
1104
1198
  }
1105
1199
  function following(el, root) {
1106
1200
  const firstChild = el.firstChild;
1107
- if (firstChild) {
1201
+ const isElmentTypeValid = el.nodeType === 1 /* NodeType.ELEMENT_NODE */ || el.nodeType === 9 /* NodeType.DOCUMENT_NODE */;
1202
+ // 如果当前 el 不是 element 或 document 元素,则可以直接不递归他的子元素了
1203
+ if (firstChild && isElmentTypeValid) {
1108
1204
  return firstChild;
1109
1205
  }
1110
1206
  let current = el;
@@ -1345,10 +1441,10 @@ class TaroElement extends TaroNode {
1345
1441
  });
1346
1442
  }
1347
1443
  getElementsByClassName(className) {
1444
+ const classNames = className.trim().split(/\s+/);
1348
1445
  return treeToArray(this, (el) => {
1349
1446
  const classList = el.classList;
1350
- const classNames = className.trim().split(/\s+/);
1351
- return classNames.every(c => classList.has(c));
1447
+ return classNames.every(c => classList.contains(c));
1352
1448
  });
1353
1449
  }
1354
1450
  dispatchEvent(event) {
@@ -2371,13 +2467,13 @@ class TaroEvent {
2371
2467
  this.defaultPrevented = true;
2372
2468
  }
2373
2469
  get target() {
2374
- var _a, _b;
2470
+ var _a, _b, _c;
2375
2471
  const cacheTarget = this.cacheTarget;
2376
2472
  if (!cacheTarget) {
2377
2473
  const target = Object.create(((_a = this.mpEvent) === null || _a === void 0 ? void 0 : _a.target) || null);
2378
- const element = env.document.getElementById(target.id);
2474
+ const element = env.document.getElementById(((_b = target.dataset) === null || _b === void 0 ? void 0 : _b.sid) || target.id || null);
2379
2475
  target.dataset = element !== null ? element.dataset : EMPTY_OBJ;
2380
- for (const key in (_b = this.mpEvent) === null || _b === void 0 ? void 0 : _b.detail) {
2476
+ for (const key in (_c = this.mpEvent) === null || _c === void 0 ? void 0 : _c.detail) {
2381
2477
  target[key] = this.mpEvent.detail[key];
2382
2478
  }
2383
2479
  this.cacheTarget = target;
@@ -2388,19 +2484,19 @@ class TaroEvent {
2388
2484
  }
2389
2485
  }
2390
2486
  get currentTarget() {
2391
- var _a, _b, _c, _d;
2487
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2392
2488
  const cacheCurrentTarget = this.cacheCurrentTarget;
2393
2489
  if (!cacheCurrentTarget) {
2394
2490
  const doc = env.document;
2395
2491
  const currentTarget = Object.create(((_a = this.mpEvent) === null || _a === void 0 ? void 0 : _a.currentTarget) || null);
2396
- const element = doc.getElementById(currentTarget.id);
2397
- const targetElement = doc.getElementById(((_c = (_b = this.mpEvent) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.id) || null);
2492
+ const element = doc.getElementById(((_b = currentTarget.dataset) === null || _b === void 0 ? void 0 : _b.sid) || currentTarget.id || null);
2493
+ const targetElement = doc.getElementById(((_e = (_d = (_c = this.mpEvent) === null || _c === void 0 ? void 0 : _c.target) === null || _d === void 0 ? void 0 : _d.dataset) === null || _e === void 0 ? void 0 : _e.sid) || ((_g = (_f = this.mpEvent) === null || _f === void 0 ? void 0 : _f.target) === null || _g === void 0 ? void 0 : _g.id) || null);
2398
2494
  if (element === null || (element && element === targetElement)) {
2399
2495
  this.cacheCurrentTarget = this.target;
2400
2496
  return this.target;
2401
2497
  }
2402
2498
  currentTarget.dataset = element.dataset;
2403
- for (const key in (_d = this.mpEvent) === null || _d === void 0 ? void 0 : _d.detail) {
2499
+ for (const key in (_h = this.mpEvent) === null || _h === void 0 ? void 0 : _h.detail) {
2404
2500
  currentTarget[key] = this.mpEvent.detail[key];
2405
2501
  }
2406
2502
  this.cacheCurrentTarget = currentTarget;
@@ -2458,7 +2554,8 @@ function eventHandler(event) {
2458
2554
  const dispatch = () => {
2459
2555
  const e = createEvent(event, node);
2460
2556
  hooks.call('modifyTaroEvent', e, node);
2461
- node.dispatchEvent(e);
2557
+ hooks.call('dispatchTaroEvent', e, node);
2558
+ hooks.call('dispatchTaroEventFinish', e, node);
2462
2559
  };
2463
2560
  if (hooks.isExist('batchedEventUpdates')) {
2464
2561
  const type = event.type;
@@ -2488,6 +2585,13 @@ function eventHandler(event) {
2488
2585
  }
2489
2586
 
2490
2587
  class FormElement extends TaroElement {
2588
+ get type() {
2589
+ var _a;
2590
+ return (_a = this.props[TYPE]) !== null && _a !== void 0 ? _a : '';
2591
+ }
2592
+ set type(val) {
2593
+ this.setAttribute(TYPE, val);
2594
+ }
2491
2595
  get value() {
2492
2596
  // eslint-disable-next-line dot-notation
2493
2597
  const val = this.props[VALUE];
@@ -2594,7 +2698,7 @@ class TaroRootElement extends TaroElement {
2594
2698
  }
2595
2699
  performUpdate(initRender = false, prerender) {
2596
2700
  this.pendingUpdate = true;
2597
- const ctx = this.ctx;
2701
+ const ctx = hooks.call('proxyToRaw', this.ctx);
2598
2702
  setTimeout(() => {
2599
2703
  const setDataMark = `${SET_DATA} 开始时间戳 ${Date.now()}`;
2600
2704
  perf.start(setDataMark);
@@ -2747,6 +2851,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2747
2851
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2748
2852
  PERFORMANCE OF THIS SOFTWARE.
2749
2853
  ***************************************************************************** */
2854
+ /* global Reflect, Promise */
2855
+
2750
2856
 
2751
2857
  function __classPrivateFieldGet(receiver, state, kind, f) {
2752
2858
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
@@ -2879,6 +2985,12 @@ _URLSearchParams_dict = new WeakMap();
2879
2985
 
2880
2986
  var _URL_hash, _URL_hostname, _URL_pathname, _URL_port, _URL_protocol, _URL_search;
2881
2987
  class URL {
2988
+ static createObjectURL() {
2989
+ throw new Error('Oops, not support URL.createObjectURL() in miniprogram.');
2990
+ }
2991
+ static revokeObjectURL() {
2992
+ throw new Error('Oops, not support URL.revokeObjectURL() in miniprogram.');
2993
+ }
2882
2994
  constructor(url, base) {
2883
2995
  /* private property */
2884
2996
  _URL_hash.set(this, '');
@@ -2898,12 +3010,6 @@ class URL {
2898
3010
  __classPrivateFieldSet(this, _URL_protocol, protocol, "f");
2899
3011
  __classPrivateFieldSet(this, _URL_search, new URLSearchParams(search), "f");
2900
3012
  }
2901
- static createObjectURL() {
2902
- throw new Error('Oops, not support URL.createObjectURL() in miniprogram.');
2903
- }
2904
- static revokeObjectURL() {
2905
- throw new Error('Oops, not support URL.revokeObjectURL() in miniprogram.');
2906
- }
2907
3013
  /* public property */
2908
3014
  get protocol() {
2909
3015
  return __classPrivateFieldGet(this, _URL_protocol, "f");
@@ -3139,9 +3245,6 @@ class AnchorElement extends TaroElement {
3139
3245
  }
3140
3246
  }
3141
3247
 
3142
- class CustomWrapperElement extends TaroElement {
3143
- }
3144
-
3145
3248
  class TaroDocument extends TaroElement {
3146
3249
  constructor() {
3147
3250
  super();
@@ -3162,9 +3265,6 @@ class TaroDocument extends TaroElement {
3162
3265
  case nodeName === A:
3163
3266
  element = new AnchorElement();
3164
3267
  break;
3165
- case nodeName === CUSTOM_WRAPPER:
3166
- element = new CustomWrapperElement();
3167
- break;
3168
3268
  default:
3169
3269
  element = new TaroElement();
3170
3270
  break;
@@ -3333,7 +3433,7 @@ class History extends Events {
3333
3433
  return __classPrivateFieldGet(this, _History_stack, "f").length;
3334
3434
  }
3335
3435
  get state() {
3336
- return __classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")];
3436
+ return __classPrivateFieldGet(this, _History_stack, "f")[__classPrivateFieldGet(this, _History_cur, "f")].state;
3337
3437
  }
3338
3438
  /* public method */
3339
3439
  go(delta) {
@@ -3829,7 +3929,7 @@ function getOnHideEventKey(path) {
3829
3929
  function createPageConfig(component, pageName, data, pageConfig) {
3830
3930
  // 小程序 Page 构造器是一个傲娇小公主,不能把复杂的对象挂载到参数上
3831
3931
  const id = pageName !== null && pageName !== void 0 ? pageName : `taro_page_${pageId()}`;
3832
- const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES] = hooks.call('getMiniLifecycleImpl').page;
3932
+ const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES,] = hooks.call('getMiniLifecycleImpl').page;
3833
3933
  let pageElement = null;
3834
3934
  let unmounting = false;
3835
3935
  let prepareMountList = [];
@@ -3955,8 +4055,19 @@ function createPageConfig(component, pageName, data, pageConfig) {
3955
4055
  }
3956
4056
  };
3957
4057
  LIFECYCLES.forEach((lifecycle) => {
4058
+ let isDefer = false;
4059
+ lifecycle = lifecycle.replace(/^defer:/, () => {
4060
+ isDefer = true;
4061
+ return '';
4062
+ });
3958
4063
  config[lifecycle] = function () {
3959
- return safeExecute(this.$taroPath, lifecycle, ...arguments);
4064
+ const exec = () => safeExecute(this.$taroPath, lifecycle, ...arguments);
4065
+ if (isDefer) {
4066
+ hasLoaded.then(exec);
4067
+ }
4068
+ else {
4069
+ return exec();
4070
+ }
3960
4071
  };
3961
4072
  });
3962
4073
  // onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
@@ -3964,7 +4075,8 @@ function createPageConfig(component, pageName, data, pageConfig) {
3964
4075
  var _a;
3965
4076
  if (component[lifecycle] ||
3966
4077
  ((_a = component.prototype) === null || _a === void 0 ? void 0 : _a[lifecycle]) ||
3967
- component[lifecycle.replace(/^on/, 'enable')]) {
4078
+ component[lifecycle.replace(/^on/, 'enable')] ||
4079
+ (pageConfig === null || pageConfig === void 0 ? void 0 : pageConfig[lifecycle.replace(/^on/, 'enable')])) {
3968
4080
  config[lifecycle] = function (...args) {
3969
4081
  var _a;
3970
4082
  const target = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.target;
@@ -3994,7 +4106,8 @@ function createComponentConfig(component, componentName, data) {
3994
4106
  [ATTACHED]() {
3995
4107
  var _a;
3996
4108
  perf.start(PAGE_INIT);
3997
- const path = getPath(id, { id: ((_a = this.getPageId) === null || _a === void 0 ? void 0 : _a.call(this)) || pageId() });
4109
+ this.pageIdCache = ((_a = this.getPageId) === null || _a === void 0 ? void 0 : _a.call(this)) || pageId();
4110
+ const path = getPath(id, { id: this.pageIdCache });
3998
4111
  Current.app.mount(component, path, () => {
3999
4112
  componentElement = env.document.getElementById(path);
4000
4113
  ensure(componentElement !== null, '没有找到组件实例。');
@@ -4007,7 +4120,7 @@ function createComponentConfig(component, componentName, data) {
4007
4120
  });
4008
4121
  },
4009
4122
  [DETACHED]() {
4010
- const path = getPath(id, { id: this.getPageId() });
4123
+ const path = getPath(id, { id: this.pageIdCache });
4011
4124
  Current.app.unmount(path, () => {
4012
4125
  instances.delete(path);
4013
4126
  if (componentElement) {
@@ -4076,18 +4189,27 @@ function createRecursiveComponentConfig(componentName) {
4076
4189
  } }, lifeCycles);
4077
4190
  }
4078
4191
 
4192
+ const TIMEOUT = 100;
4079
4193
  const nextTick = (cb, ctx) => {
4080
- var _a, _b, _c;
4194
+ const beginTime = Date.now();
4081
4195
  const router = Current.router;
4082
4196
  const timerFunc = () => {
4083
4197
  setTimeout(function () {
4084
4198
  ctx ? cb.call(ctx) : cb();
4085
4199
  }, 1);
4086
4200
  };
4087
- if (router !== null) {
4088
- let pageElement = null;
4089
- const path = router.$taroPath;
4090
- pageElement = env.document.getElementById(path);
4201
+ if (router === null)
4202
+ return timerFunc();
4203
+ const path = router.$taroPath;
4204
+ /**
4205
+ * 三种情况
4206
+ * 1. 调用 nextTick 时,pendingUpdate 已经从 true 变为 false(即已更新完成),那么需要光等 100ms
4207
+ * 2. 调用 nextTick 时,pendingUpdate 为 true,那么刚好可以搭上便车
4208
+ * 3. 调用 nextTick 时,pendingUpdate 还是 false,框架仍未启动更新逻辑,这时最多轮询 100ms,等待 pendingUpdate 变为 true。
4209
+ */
4210
+ function next() {
4211
+ var _a, _b, _c;
4212
+ const pageElement = env.document.getElementById(path);
4091
4213
  if (pageElement === null || pageElement === void 0 ? void 0 : pageElement.pendingUpdate) {
4092
4214
  if (isWebPlatform()) {
4093
4215
  // eslint-disable-next-line dot-notation
@@ -4099,14 +4221,15 @@ const nextTick = (cb, ctx) => {
4099
4221
  pageElement.enqueueUpdateCallback(cb, ctx);
4100
4222
  }
4101
4223
  }
4102
- else {
4224
+ else if (Date.now() - beginTime > TIMEOUT) {
4103
4225
  timerFunc();
4104
4226
  }
4227
+ else {
4228
+ setTimeout(() => next(), 20);
4229
+ }
4105
4230
  }
4106
- else {
4107
- timerFunc();
4108
- }
4231
+ next();
4109
4232
  };
4110
4233
 
4111
- export { Current, FormElement, History, Location, MutationObserver, SVGElement, Style, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, URL, URLSearchParams, addLeadingSlash, _caf as cancelAnimationFrame, createComponentConfig, createEvent, createPageConfig, createRecursiveComponentConfig, document$1 as document, eventCenter, eventHandler, eventSource, getComputedStyle, getCurrentInstance, getPageInstance, history, hydrate, incrementId, injectPageInstance, location, nav as navigator, nextTick, now, options, parseUrl, removePageInstance, _raf as requestAnimationFrame, safeExecute, stringify, window$1 as window };
4234
+ export { A, APP, BEHAVIORS, BODY, CATCHMOVE, CATCH_VIEW, CHANGE, CLASS, COMMENT, CONFIRM, CONTAINER, CONTEXT_ACTIONS, CURRENT_TARGET, CUSTOM_WRAPPER, Current, DATASET, DATE, DOCUMENT_ELEMENT_NAME, DOCUMENT_FRAGMENT, EVENT_CALLBACK_RESULT, EXTERNAL_CLASSES, FOCUS, FormElement, HEAD, HOOKS_APP_ID, HTML, History, ID, INPUT, KEY_CODE, Location, MutationObserver, OBJECT, ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, OPTIONS, PAGE_INIT, PROPERTY_THRESHOLD, PROPS, PURE_VIEW, ROOT_STR, SET_DATA, SET_TIMEOUT, STATIC_VIEW, STYLE, SVGElement, Style, TARGET, TARO_RUNTIME, TIME_STAMP, TOUCHMOVE, TYPE, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, UID, URL, URLSearchParams, VALUE, VIEW, addLeadingSlash, _caf as cancelAnimationFrame, createComponentConfig, createEvent, createPageConfig, createRecursiveComponentConfig, document$1 as document, env, eventCenter, eventHandler, eventSource, getComputedStyle, getCurrentInstance, getOnHideEventKey, getOnReadyEventKey, getOnShowEventKey, getPageInstance, getPath, history, hydrate, incrementId, injectPageInstance, location, nav as navigator, nextTick, now, options, parseUrl, removePageInstance, _raf as requestAnimationFrame, safeExecute, stringify, window$1 as window };
4112
4235
  //# sourceMappingURL=runtime.esm.js.map