@tarojs/plugin-framework-react 3.7.0-alpha.2 → 3.7.0-alpha.20
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/dist/api-loader.js +3 -0
- package/dist/api-loader.js.map +1 -1
- package/dist/index.js +263 -62
- package/dist/index.js.map +1 -1
- package/dist/runtime.js +246 -46
- package/dist/runtime.js.map +1 -1
- package/package.json +12 -5
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EMPTY_OBJ, isFunction, isArray, isWebPlatform, hooks, ensure } from '@tarojs/shared';
|
|
2
|
-
import { Current, getPageInstance, injectPageInstance, incrementId, document, safeExecute, eventHandler, addLeadingSlash
|
|
1
|
+
import { EMPTY_OBJ, isFunction, isArray, isWebPlatform, hooks, ensure, isUndefined } from '@tarojs/shared';
|
|
2
|
+
import { Current, getPageInstance, injectPageInstance, incrementId, document, getPath, window, CONTEXT_ACTIONS, safeExecute, removePageInstance, ON_READY, requestAnimationFrame, eventCenter, getOnReadyEventKey, ON_SHOW, getOnShowEventKey, ON_HIDE, getOnHideEventKey, eventHandler, addLeadingSlash } from '@tarojs/runtime';
|
|
3
3
|
|
|
4
4
|
const reactMeta = {
|
|
5
5
|
PageContext: EMPTY_OBJ,
|
|
@@ -473,7 +473,9 @@ function createReactApp(App, react, dom, config) {
|
|
|
473
473
|
const getNativeCompId = incrementId();
|
|
474
474
|
let h;
|
|
475
475
|
let ReactDOM;
|
|
476
|
-
|
|
476
|
+
let nativeComponentApp;
|
|
477
|
+
function initNativeComponentEntry(params) {
|
|
478
|
+
const { R, ReactDOM, cb, isDefaultEntryDom = true } = params;
|
|
477
479
|
class NativeComponentWrapper extends R.Component {
|
|
478
480
|
constructor() {
|
|
479
481
|
super(...arguments);
|
|
@@ -488,7 +490,8 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
488
490
|
}
|
|
489
491
|
render() {
|
|
490
492
|
return (h('root', {
|
|
491
|
-
ref: this.root
|
|
493
|
+
ref: this.root,
|
|
494
|
+
id: this.props.compId
|
|
492
495
|
}, this.props.renderComponent(this.ctx)));
|
|
493
496
|
}
|
|
494
497
|
}
|
|
@@ -500,9 +503,15 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
500
503
|
};
|
|
501
504
|
}
|
|
502
505
|
componentDidMount() {
|
|
503
|
-
|
|
506
|
+
if (isDefaultEntryDom) {
|
|
507
|
+
Current.app = this;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
nativeComponentApp = this;
|
|
511
|
+
}
|
|
512
|
+
cb && cb();
|
|
504
513
|
}
|
|
505
|
-
mount(Component, compId, getCtx) {
|
|
514
|
+
mount(Component, compId, getCtx, cb) {
|
|
506
515
|
const isReactComponent = isClassComponent(R, Component);
|
|
507
516
|
const inject = (node) => node && injectPageInstance(node, compId);
|
|
508
517
|
const refs = isReactComponent ? { ref: inject } : {
|
|
@@ -516,6 +525,7 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
516
525
|
compId,
|
|
517
526
|
element: h(NativeComponentWrapper, {
|
|
518
527
|
key: compId,
|
|
528
|
+
compId,
|
|
519
529
|
getCtx,
|
|
520
530
|
renderComponent(ctx) {
|
|
521
531
|
return h(reactMeta.PageContext.Provider, { value: compId }, h(Component, Object.assign(Object.assign(Object.assign({}, (ctx.data || (ctx.data = {})).props), refs), { $scope: ctx })));
|
|
@@ -524,9 +534,9 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
524
534
|
};
|
|
525
535
|
this.setState({
|
|
526
536
|
components: [...this.state.components, item]
|
|
527
|
-
});
|
|
537
|
+
}, () => cb && cb());
|
|
528
538
|
}
|
|
529
|
-
unmount(compId) {
|
|
539
|
+
unmount(compId, cb) {
|
|
530
540
|
const components = this.state.components;
|
|
531
541
|
const index = components.findIndex(item => item.compId === compId);
|
|
532
542
|
const next = [...components.slice(0, index), ...components.slice(index + 1)];
|
|
@@ -534,6 +544,7 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
534
544
|
components: next
|
|
535
545
|
}, () => {
|
|
536
546
|
removePageInstance(compId);
|
|
547
|
+
cb && cb();
|
|
537
548
|
});
|
|
538
549
|
}
|
|
539
550
|
render() {
|
|
@@ -542,15 +553,187 @@ function initNativeComponentEntry(R, ReactDOM) {
|
|
|
542
553
|
}
|
|
543
554
|
}
|
|
544
555
|
setReconciler(ReactDOM);
|
|
545
|
-
|
|
556
|
+
let app = document.getElementById('app');
|
|
557
|
+
if (!isDefaultEntryDom && !nativeComponentApp) {
|
|
558
|
+
// create
|
|
559
|
+
const nativeApp = document.createElement('nativeComponent');
|
|
560
|
+
// insert
|
|
561
|
+
app.appendChild(nativeApp);
|
|
562
|
+
app = nativeApp;
|
|
563
|
+
}
|
|
546
564
|
ReactDOM.render(h(Entry, {}), app);
|
|
547
565
|
}
|
|
566
|
+
function createNativePageConfig(Component, pageName, data, react, reactdom, pageConfig) {
|
|
567
|
+
reactMeta.R = react;
|
|
568
|
+
h = react.createElement;
|
|
569
|
+
ReactDOM = reactdom;
|
|
570
|
+
setReconciler(ReactDOM);
|
|
571
|
+
const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES] = hooks.call('getMiniLifecycleImpl').page;
|
|
572
|
+
let unmounting = false;
|
|
573
|
+
let prepareMountList = [];
|
|
574
|
+
let pageElement = null;
|
|
575
|
+
let loadResolver;
|
|
576
|
+
let hasLoaded;
|
|
577
|
+
const id = pageName !== null && pageName !== void 0 ? pageName : `taro_page_${getNativeCompId()}`;
|
|
578
|
+
function setCurrentRouter(page) {
|
|
579
|
+
const router = page.route || page.__route__ || page.$taroPath;
|
|
580
|
+
Current.router = {
|
|
581
|
+
params: page.$taroParams,
|
|
582
|
+
path: addLeadingSlash(router),
|
|
583
|
+
$taroPath: page.$taroPath,
|
|
584
|
+
onReady: getOnReadyEventKey(id),
|
|
585
|
+
onShow: getOnShowEventKey(id),
|
|
586
|
+
onHide: getOnHideEventKey(id)
|
|
587
|
+
};
|
|
588
|
+
if (!isUndefined(page.exitState)) {
|
|
589
|
+
Current.router.exitState = page.exitState;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
const pageObj = {
|
|
593
|
+
options: pageConfig,
|
|
594
|
+
[ONLOAD](options = {}, cb) {
|
|
595
|
+
hasLoaded = new Promise(resolve => { loadResolver = resolve; });
|
|
596
|
+
Current.page = this;
|
|
597
|
+
this.config = pageConfig || {};
|
|
598
|
+
// this.$taroPath 是页面唯一标识
|
|
599
|
+
const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() });
|
|
600
|
+
const $taroPath = this.$taroPath = getPath(id, uniqueOptions);
|
|
601
|
+
// this.$taroParams 作为暴露给开发者的页面参数对象,可以被随意修改
|
|
602
|
+
if (this.$taroParams == null) {
|
|
603
|
+
this.$taroParams = uniqueOptions;
|
|
604
|
+
}
|
|
605
|
+
setCurrentRouter(this);
|
|
606
|
+
window.trigger(CONTEXT_ACTIONS.INIT, $taroPath);
|
|
607
|
+
const mountCallback = () => {
|
|
608
|
+
pageElement = document.getElementById($taroPath);
|
|
609
|
+
ensure(pageElement !== null, '没有找到页面实例。');
|
|
610
|
+
safeExecute($taroPath, ONLOAD, this.$taroParams);
|
|
611
|
+
loadResolver();
|
|
612
|
+
pageElement.ctx = this;
|
|
613
|
+
pageElement.performUpdate(true, cb);
|
|
614
|
+
};
|
|
615
|
+
const mount = () => {
|
|
616
|
+
if (!Current.app) {
|
|
617
|
+
initNativeComponentEntry({
|
|
618
|
+
R: react,
|
|
619
|
+
ReactDOM,
|
|
620
|
+
cb: () => {
|
|
621
|
+
Current.app.mount(Component, $taroPath, () => this, mountCallback);
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
Current.app.mount(Component, $taroPath, () => this, mountCallback);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
if (unmounting) {
|
|
630
|
+
prepareMountList.push(mount);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
mount();
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
[ONUNLOAD]() {
|
|
637
|
+
const $taroPath = this.$taroPath;
|
|
638
|
+
// 销毁当前页面的上下文信息
|
|
639
|
+
window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath);
|
|
640
|
+
// 触发onUnload生命周期
|
|
641
|
+
safeExecute($taroPath, ONUNLOAD);
|
|
642
|
+
resetCurrent();
|
|
643
|
+
unmounting = true;
|
|
644
|
+
Current.app.unmount($taroPath, () => {
|
|
645
|
+
unmounting = false;
|
|
646
|
+
removePageInstance($taroPath);
|
|
647
|
+
if (pageElement) {
|
|
648
|
+
pageElement.ctx = null;
|
|
649
|
+
pageElement = null;
|
|
650
|
+
}
|
|
651
|
+
if (prepareMountList.length) {
|
|
652
|
+
prepareMountList.forEach(fn => fn());
|
|
653
|
+
prepareMountList = [];
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
},
|
|
657
|
+
[ONREADY]() {
|
|
658
|
+
hasLoaded.then(() => {
|
|
659
|
+
// 触发生命周期
|
|
660
|
+
safeExecute(this.$taroPath, ON_READY);
|
|
661
|
+
// 通过事件触发子组件的生命周期
|
|
662
|
+
requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)));
|
|
663
|
+
this.onReady.called = true;
|
|
664
|
+
});
|
|
665
|
+
},
|
|
666
|
+
[ONSHOW](options = {}) {
|
|
667
|
+
hasLoaded.then(() => {
|
|
668
|
+
// 设置 Current 的 page 和 router
|
|
669
|
+
Current.page = this;
|
|
670
|
+
setCurrentRouter(this);
|
|
671
|
+
// 恢复上下文信息
|
|
672
|
+
window.trigger(CONTEXT_ACTIONS.RECOVER, this.$taroPath);
|
|
673
|
+
// 触发生命周期
|
|
674
|
+
safeExecute(this.$taroPath, ON_SHOW, options);
|
|
675
|
+
// 通过事件触发子组件的生命周期
|
|
676
|
+
requestAnimationFrame(() => eventCenter.trigger(getOnShowEventKey(id)));
|
|
677
|
+
});
|
|
678
|
+
},
|
|
679
|
+
[ONHIDE]() {
|
|
680
|
+
// 缓存当前页面上下文信息
|
|
681
|
+
window.trigger(CONTEXT_ACTIONS.RESTORE, this.$taroPath);
|
|
682
|
+
// 设置 Current 的 page 和 router
|
|
683
|
+
if (Current.page === this) {
|
|
684
|
+
Current.page = null;
|
|
685
|
+
Current.router = null;
|
|
686
|
+
}
|
|
687
|
+
// 触发生命周期
|
|
688
|
+
safeExecute(this.$taroPath, ON_HIDE);
|
|
689
|
+
// 通过事件触发子组件的生命周期
|
|
690
|
+
eventCenter.trigger(getOnHideEventKey(id));
|
|
691
|
+
},
|
|
692
|
+
};
|
|
693
|
+
function resetCurrent() {
|
|
694
|
+
// 小程序插件页面卸载之后返回到宿主页面时,需重置Current页面和路由。否则引发插件组件二次加载异常 fix:#11991
|
|
695
|
+
Current.page = null;
|
|
696
|
+
Current.router = null;
|
|
697
|
+
}
|
|
698
|
+
LIFECYCLES.forEach((lifecycle) => {
|
|
699
|
+
pageObj[lifecycle] = function () {
|
|
700
|
+
return safeExecute(this.$taroPath, lifecycle, ...arguments);
|
|
701
|
+
};
|
|
702
|
+
});
|
|
703
|
+
// onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
|
|
704
|
+
SIDE_EFFECT_LIFECYCLES.forEach(lifecycle => {
|
|
705
|
+
var _a;
|
|
706
|
+
if (Component[lifecycle] ||
|
|
707
|
+
((_a = Component.prototype) === null || _a === void 0 ? void 0 : _a[lifecycle]) ||
|
|
708
|
+
Component[lifecycle.replace(/^on/, 'enable')]) {
|
|
709
|
+
pageObj[lifecycle] = function (...args) {
|
|
710
|
+
var _a;
|
|
711
|
+
const target = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.target;
|
|
712
|
+
if (target === null || target === void 0 ? void 0 : target.id) {
|
|
713
|
+
const id = target.id;
|
|
714
|
+
const element = document.getElementById(id);
|
|
715
|
+
if (element) {
|
|
716
|
+
target.dataset = element.dataset;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return safeExecute(this.$taroPath, lifecycle, ...args);
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
pageObj.eh = eventHandler;
|
|
724
|
+
if (!isUndefined(data)) {
|
|
725
|
+
pageObj.data = data;
|
|
726
|
+
}
|
|
727
|
+
hooks.call('modifyPageObject', pageObj);
|
|
728
|
+
return pageObj;
|
|
729
|
+
}
|
|
548
730
|
function createNativeComponentConfig(Component, react, reactdom, componentConfig) {
|
|
549
731
|
var _a, _b;
|
|
550
732
|
reactMeta.R = react;
|
|
551
733
|
h = react.createElement;
|
|
552
734
|
ReactDOM = reactdom;
|
|
553
735
|
setReconciler(ReactDOM);
|
|
736
|
+
const { isNewBlended } = componentConfig;
|
|
554
737
|
const componentObj = {
|
|
555
738
|
options: componentConfig,
|
|
556
739
|
properties: {
|
|
@@ -564,22 +747,37 @@ function createNativeComponentConfig(Component, react, reactdom, componentConfig
|
|
|
564
747
|
}
|
|
565
748
|
},
|
|
566
749
|
created() {
|
|
567
|
-
|
|
568
|
-
|
|
750
|
+
const app = (isNewBlended ? nativeComponentApp : Current.app);
|
|
751
|
+
if (!app) {
|
|
752
|
+
initNativeComponentEntry({
|
|
753
|
+
R: react,
|
|
754
|
+
ReactDOM,
|
|
755
|
+
isDefaultEntryDom: !isNewBlended
|
|
756
|
+
});
|
|
569
757
|
}
|
|
570
758
|
},
|
|
571
759
|
attached() {
|
|
572
760
|
const compId = this.compId = getNativeCompId();
|
|
573
761
|
setCurrent(compId);
|
|
574
762
|
this.config = componentConfig;
|
|
575
|
-
|
|
763
|
+
const app = (isNewBlended ? nativeComponentApp : Current.app);
|
|
764
|
+
app.mount(Component, compId, () => this, () => {
|
|
765
|
+
const instance = getPageInstance(compId);
|
|
766
|
+
if (instance && instance.node) {
|
|
767
|
+
const el = document.getElementById(instance.node.uid);
|
|
768
|
+
if (el) {
|
|
769
|
+
el.ctx = this;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
});
|
|
576
773
|
},
|
|
577
774
|
ready() {
|
|
578
775
|
safeExecute(this.compId, 'onReady');
|
|
579
776
|
},
|
|
580
777
|
detached() {
|
|
581
778
|
resetCurrent();
|
|
582
|
-
Current.app
|
|
779
|
+
const app = (isNewBlended ? nativeComponentApp : Current.app);
|
|
780
|
+
app.unmount(this.compId);
|
|
583
781
|
},
|
|
584
782
|
pageLifetimes: {
|
|
585
783
|
show(options) {
|
|
@@ -604,37 +802,6 @@ function createNativeComponentConfig(Component, react, reactdom, componentConfig
|
|
|
604
802
|
Current.page = null;
|
|
605
803
|
Current.router = null;
|
|
606
804
|
}
|
|
607
|
-
function setCurrent(compId) {
|
|
608
|
-
const pages = getCurrentPages();
|
|
609
|
-
const currentPage = pages[pages.length - 1];
|
|
610
|
-
if (Current.page === currentPage)
|
|
611
|
-
return;
|
|
612
|
-
Current.page = currentPage;
|
|
613
|
-
const route = currentPage.route || currentPage.__route__;
|
|
614
|
-
const router = {
|
|
615
|
-
params: currentPage.options || {},
|
|
616
|
-
path: addLeadingSlash(route),
|
|
617
|
-
$taroPath: compId,
|
|
618
|
-
onReady: '',
|
|
619
|
-
onHide: '',
|
|
620
|
-
onShow: ''
|
|
621
|
-
};
|
|
622
|
-
Current.router = router;
|
|
623
|
-
if (!currentPage.options) {
|
|
624
|
-
// 例如在微信小程序中,页面 options 的设置时机比组件 attached 慢
|
|
625
|
-
Object.defineProperty(currentPage, 'options', {
|
|
626
|
-
enumerable: true,
|
|
627
|
-
configurable: true,
|
|
628
|
-
get() {
|
|
629
|
-
return this._optionsValue;
|
|
630
|
-
},
|
|
631
|
-
set(value) {
|
|
632
|
-
router.params = value;
|
|
633
|
-
this._optionsValue = value;
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
805
|
// onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
|
|
639
806
|
if (Component.onShareAppMessage ||
|
|
640
807
|
((_a = Component.prototype) === null || _a === void 0 ? void 0 : _a.onShareAppMessage) ||
|
|
@@ -660,13 +827,46 @@ function createNativeComponentConfig(Component, react, reactdom, componentConfig
|
|
|
660
827
|
}
|
|
661
828
|
return componentObj;
|
|
662
829
|
}
|
|
830
|
+
function setCurrent(compId) {
|
|
831
|
+
if (!getCurrentPages || typeof getCurrentPages !== 'function')
|
|
832
|
+
return;
|
|
833
|
+
const pages = getCurrentPages();
|
|
834
|
+
const currentPage = pages[pages.length - 1];
|
|
835
|
+
if (Current.page === currentPage)
|
|
836
|
+
return;
|
|
837
|
+
Current.page = currentPage;
|
|
838
|
+
const route = currentPage.route || currentPage.__route__;
|
|
839
|
+
const router = {
|
|
840
|
+
params: currentPage.options || {},
|
|
841
|
+
path: addLeadingSlash(route),
|
|
842
|
+
$taroPath: compId,
|
|
843
|
+
onReady: '',
|
|
844
|
+
onHide: '',
|
|
845
|
+
onShow: ''
|
|
846
|
+
};
|
|
847
|
+
Current.router = router;
|
|
848
|
+
if (!currentPage.options) {
|
|
849
|
+
// 例如在微信小程序中,页面 options 的设置时机比组件 attached 慢
|
|
850
|
+
Object.defineProperty(currentPage, 'options', {
|
|
851
|
+
enumerable: true,
|
|
852
|
+
configurable: true,
|
|
853
|
+
get() {
|
|
854
|
+
return this._optionsValue;
|
|
855
|
+
},
|
|
856
|
+
set(value) {
|
|
857
|
+
router.params = value;
|
|
858
|
+
this._optionsValue = value;
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
}
|
|
663
863
|
|
|
664
864
|
hooks.tap('initNativeApi', function (taro) {
|
|
665
865
|
for (const hook in taroHooks) {
|
|
666
866
|
taro[hook] = taroHooks[hook];
|
|
667
867
|
}
|
|
668
868
|
});
|
|
669
|
-
if (__TARO_FRAMEWORK__ === 'preact') {
|
|
869
|
+
if (__TARO_FRAMEWORK__ === 'preact' && process.env.TARO_PLATFORM === 'mini') {
|
|
670
870
|
const options = require('preact').options;
|
|
671
871
|
const oldVNodeHook = options.vnode;
|
|
672
872
|
const oldDiffedHook = options.diffed;
|
|
@@ -729,5 +929,5 @@ if (__TARO_FRAMEWORK__ === 'preact') {
|
|
|
729
929
|
// })
|
|
730
930
|
}
|
|
731
931
|
|
|
732
|
-
export { connectReactPage, createNativeComponentConfig, createReactApp, setReconciler, useAddToFavorites, useDidHide, useDidShow, useError, useLaunch, useLoad, useOptionMenuClick, usePageNotFound, usePageScroll, usePullDownRefresh, usePullIntercept, useReachBottom, useReady, useResize, useRouter, useSaveExitState, useScope, useShareAppMessage, useShareTimeline, useTabItemTap, useTitleClick, useUnhandledRejection, useUnload };
|
|
932
|
+
export { connectReactPage, createNativeComponentConfig, createNativePageConfig, createReactApp, setReconciler, useAddToFavorites, useDidHide, useDidShow, useError, useLaunch, useLoad, useOptionMenuClick, usePageNotFound, usePageScroll, usePullDownRefresh, usePullIntercept, useReachBottom, useReady, useResize, useRouter, useSaveExitState, useScope, useShareAppMessage, useShareTimeline, useTabItemTap, useTitleClick, useUnhandledRejection, useUnload };
|
|
733
933
|
//# sourceMappingURL=runtime.js.map
|