@tarojs/router 3.6.0-canary.0 → 3.6.0-canary.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.
package/dist/api.js CHANGED
@@ -39,6 +39,7 @@ function processNavigateUrl(option) {
39
39
  function navigate(option, method) {
40
40
  return __awaiter(this, void 0, void 0, function* () {
41
41
  return new Promise((resolve, reject) => {
42
+ stacks.method = method;
42
43
  const { success, complete, fail } = option;
43
44
  const unListen = history.listen(() => {
44
45
  const res = { errMsg: `${method}:ok` };
package/dist/index.cjs.js CHANGED
@@ -46,6 +46,12 @@ const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
46
46
  const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
47
47
  const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
48
48
  const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
49
+ const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
50
+ var _a;
51
+ const routePath = addLeadingSlash(stripBasename(path, basename));
52
+ const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
53
+ return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
54
+ };
49
55
  class RoutesAlias {
50
56
  constructor() {
51
57
  this.conf = [];
@@ -212,6 +218,8 @@ class Stacks {
212
218
  constructor() {
213
219
  this.stacks = [];
214
220
  this.backDelta = 0;
221
+ this.tabs = {};
222
+ this.methodName = '';
215
223
  }
216
224
  set delta(delta) {
217
225
  if (delta > 0) {
@@ -227,6 +235,12 @@ class Stacks {
227
235
  get delta() {
228
236
  return this.backDelta;
229
237
  }
238
+ set method(methodName) {
239
+ this.methodName = methodName;
240
+ }
241
+ get method() {
242
+ return this.methodName;
243
+ }
230
244
  get length() {
231
245
  return this.stacks.length;
232
246
  }
@@ -264,6 +278,20 @@ class Stacks {
264
278
  push(page) {
265
279
  return this.stacks.push(page);
266
280
  }
281
+ getTabs() {
282
+ return this.tabs;
283
+ }
284
+ pushTab(path) {
285
+ this.tabs[path] = this.last;
286
+ this.pop();
287
+ }
288
+ popTab(path) {
289
+ this.push(this.tabs[path]);
290
+ delete this.tabs[path];
291
+ }
292
+ removeTab(path) {
293
+ delete this.tabs[path];
294
+ }
267
295
  }
268
296
  const stacks = new Stacks();
269
297
 
@@ -294,6 +322,7 @@ function processNavigateUrl(option) {
294
322
  function navigate(option, method) {
295
323
  return __awaiter(this, void 0, void 0, function* () {
296
324
  return new Promise((resolve, reject) => {
325
+ stacks.method = method;
297
326
  const { success, complete, fail } = option;
298
327
  const unListen = exports.history.listen(() => {
299
328
  const res = { errMsg: `${method}:ok` };
@@ -470,7 +499,7 @@ class MultiPageHandler {
470
499
  this.config = config;
471
500
  this.mount();
472
501
  }
473
- get appId() { return 'app'; }
502
+ get appId() { return this.config.appId || 'app'; }
474
503
  get router() { return this.config.router || {}; }
475
504
  get routerMode() { return this.router.mode || 'hash'; }
476
505
  get customRoutes() { return this.router.customRoutes || {}; }
@@ -503,11 +532,13 @@ class MultiPageHandler {
503
532
  return Object.assign(Object.assign({}, query), options);
504
533
  }
505
534
  mount() {
506
- var _a;
507
535
  setHistoryMode(this.routerMode, this.router.basename);
508
- (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
509
- const app = document.createElement('div');
510
- app.id = this.appId;
536
+ const appId = this.appId;
537
+ let app = document.getElementById(appId);
538
+ if (!app) {
539
+ app = document.createElement('div');
540
+ app.id = appId;
541
+ }
511
542
  app.classList.add('taro_router');
512
543
  if (this.tabBarList.length > 1) {
513
544
  const container = document.createElement('div');
@@ -570,6 +601,8 @@ class MultiPageHandler {
570
601
  }
571
602
  }
572
603
 
604
+ const createStampId$1 = runtime.incrementId();
605
+ const launchStampId$1 = createStampId$1();
573
606
  // TODO 支持多路由 (APP 生命周期仅触发一次)
574
607
  /** Note: 关于多页面应用
575
608
  * - 需要配置路由映射(根目录跳转、404 页面……)
@@ -585,7 +618,7 @@ function createMultiRouter(app, config, framework) {
585
618
  const handler = new MultiPageHandler(config);
586
619
  const launchParam = {
587
620
  path: config.pageName,
588
- query: handler.getQuery(),
621
+ query: handler.getQuery(launchStampId$1),
589
622
  scene: 0,
590
623
  shareTicket: '',
591
624
  referrerInfo: {}
@@ -669,10 +702,10 @@ class PageHandler {
669
702
  constructor(config) {
670
703
  this.defaultAnimation = { duration: 300, delay: 50 };
671
704
  this.config = config;
672
- this.homePage = this.getHomePage();
705
+ this.homePage = getHomePage(this.routes[0].path, this.basename, this.customRoutes, this.config.entryPagePath);
673
706
  this.mount();
674
707
  }
675
- get appId() { return 'app'; }
708
+ get appId() { return this.config.appId || 'app'; }
676
709
  get router() { return this.config.router || {}; }
677
710
  get routerMode() { return this.router.mode || 'hash'; }
678
711
  get customRoutes() { return this.router.customRoutes || {}; }
@@ -708,9 +741,9 @@ class PageHandler {
708
741
  return [pagePath, homePage].includes(routePath) || ((_a = routesAlias.getConfig(pagePath)) === null || _a === void 0 ? void 0 : _a.includes(routePath));
709
742
  });
710
743
  }
711
- get isTabBar() {
744
+ isTabBar(pathname) {
712
745
  var _a;
713
- const routePath = addLeadingSlash(stripBasename(this.pathname, this.basename));
746
+ const routePath = addLeadingSlash(stripBasename(pathname, this.basename)).split('?')[0];
714
747
  const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
715
748
  if (typeof target === 'string') {
716
749
  return target === routePath;
@@ -722,12 +755,6 @@ class PageHandler {
722
755
  })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
723
756
  return !!pagePath && this.tabBarList.some(t => stripTrailing(t.pagePath) === pagePath);
724
757
  }
725
- getHomePage() {
726
- var _a;
727
- const routePath = addLeadingSlash(stripBasename(this.routes[0].path, this.basename));
728
- const alias = ((_a = Object.entries(this.customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
729
- return this.config.entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || this.basename;
730
- }
731
758
  isSamePage(page) {
732
759
  const routePath = stripBasename(this.pathname, this.basename);
733
760
  const pagePath = stripBasename(page === null || page === void 0 ? void 0 : page.path, this.basename);
@@ -746,21 +773,23 @@ class PageHandler {
746
773
  }
747
774
  return search.substr(1);
748
775
  }
749
- getQuery(stamp = 0, search = '', options = {}) {
776
+ getQuery(stamp = '', search = '', options = {}) {
750
777
  search = search ? `${search}&${this.search}` : this.search;
751
778
  const query = search
752
779
  ? queryString__default["default"].parse(search, { decode: false })
753
780
  : {};
754
- query.stamp = stamp.toString();
781
+ query.stamp = stamp;
755
782
  return Object.assign(Object.assign({}, query), options);
756
783
  }
757
784
  mount() {
758
- var _a;
759
785
  setHistoryMode(this.routerMode, this.router.basename);
760
- (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
761
786
  this.animation && loadAnimateStyle(this.animationDuration);
762
- const app = document.createElement('div');
763
- app.id = this.appId;
787
+ const appId = this.appId;
788
+ let app = document.getElementById(appId);
789
+ if (!app) {
790
+ app = document.createElement('div');
791
+ app.id = appId;
792
+ }
764
793
  app.classList.add('taro_router');
765
794
  if (this.tabBarList.length > 1) {
766
795
  const container = document.createElement('div');
@@ -792,18 +821,18 @@ class PageHandler {
792
821
  onLoad && (pageEl['__page'] = page);
793
822
  }
794
823
  }
795
- load(page, pageConfig = {}, stacksIndex = 0) {
824
+ load(page, pageConfig = {}, stampId, pageNo = 0) {
796
825
  var _a, _b;
797
826
  if (!page)
798
827
  return;
799
828
  // NOTE: 页面栈推入太晚可能导致 getCurrentPages 无法获取到当前页面实例
800
829
  stacks.push(page);
801
- const param = this.getQuery(stacks.length, '', page.options);
830
+ const param = this.getQuery(stampId, '', page.options);
802
831
  let pageEl = this.getPageContainer(page);
803
832
  if (pageEl) {
804
833
  setDisplay(pageEl);
805
- this.isTabBar && pageEl.classList.add('taro_tabbar_page');
806
- this.addAnimation(pageEl, stacksIndex === 0);
834
+ this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
835
+ this.addAnimation(pageEl, pageNo === 0);
807
836
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
808
837
  this.bindPageEvents(page, pageEl, pageConfig);
809
838
  }
@@ -811,8 +840,8 @@ class PageHandler {
811
840
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
812
841
  var _a;
813
842
  pageEl = this.getPageContainer(page);
814
- this.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
815
- this.addAnimation(pageEl, stacksIndex === 0);
843
+ this.isTabBar(this.pathname) && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
844
+ this.addAnimation(pageEl, pageNo === 0);
816
845
  this.onReady(page, true);
817
846
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
818
847
  this.bindPageEvents(page, pageEl, pageConfig);
@@ -850,15 +879,15 @@ class PageHandler {
850
879
  if (delta >= 1)
851
880
  this.unload(stacks.last, delta);
852
881
  }
853
- show(page, pageConfig = {}, stacksIndex = 0) {
882
+ show(page, pageConfig = {}, pageNo = 0) {
854
883
  var _a, _b;
855
884
  if (!page)
856
885
  return;
857
- const param = this.getQuery(stacks.length, '', page.options);
886
+ const param = this.getQuery(page['$taroParams']['stamp'], '', page.options);
858
887
  let pageEl = this.getPageContainer(page);
859
888
  if (pageEl) {
860
889
  setDisplay(pageEl);
861
- this.addAnimation(pageEl, stacksIndex === 0);
890
+ this.addAnimation(pageEl, pageNo === 0);
862
891
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
863
892
  this.bindPageEvents(page, pageEl, pageConfig);
864
893
  }
@@ -866,7 +895,7 @@ class PageHandler {
866
895
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
867
896
  var _a;
868
897
  pageEl = this.getPageContainer(page);
869
- this.addAnimation(pageEl, stacksIndex === 0);
898
+ this.addAnimation(pageEl, pageNo === 0);
870
899
  this.onReady(page, false);
871
900
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
872
901
  this.bindPageEvents(page, pageEl, pageConfig);
@@ -936,6 +965,8 @@ class PageHandler {
936
965
  }
937
966
  }
938
967
 
968
+ const createStampId = runtime.incrementId();
969
+ let launchStampId = createStampId();
939
970
  function createRouter(app, config, framework) {
940
971
  var _a, _b;
941
972
  RouterConfig.config = config;
@@ -953,7 +984,7 @@ function createRouter(app, config, framework) {
953
984
  const router = new UniversalRouter__default["default"](routes, { baseUrl: basename || '' });
954
985
  const launchParam = {
955
986
  path: handler.homePage,
956
- query: handler.getQuery(stacks.length),
987
+ query: handler.getQuery(launchStampId),
957
988
  scene: 0,
958
989
  shareTicket: '',
959
990
  referrerInfo: {}
@@ -962,7 +993,7 @@ function createRouter(app, config, framework) {
962
993
  (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
963
994
  app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
964
995
  const render = ({ location, action }) => __awaiter(this, void 0, void 0, function* () {
965
- var _c, _d, _e, _f, _g;
996
+ var _c, _d, _e, _f, _g, _h;
966
997
  handler.pathname = decodeURI(location.pathname);
967
998
  runtime.eventCenter.trigger('__taroRouterChange', {
968
999
  toLocation: {
@@ -1001,8 +1032,45 @@ function createRouter(app, config, framework) {
1001
1032
  }
1002
1033
  const currentPage = runtime.Current.page;
1003
1034
  const pathname = handler.pathname;
1035
+ const methodName = (_g = stacks.method) !== null && _g !== void 0 ? _g : '';
1036
+ const cacheTabs = stacks.getTabs();
1004
1037
  let shouldLoad = false;
1005
- if (action === 'POP') {
1038
+ stacks.method = '';
1039
+ if (methodName === 'reLaunch') {
1040
+ handler.unload(currentPage, stacks.length);
1041
+ // NOTE: 同时卸载缓存在tabs里面的页面实例
1042
+ for (const key in cacheTabs) {
1043
+ if (cacheTabs[key]) {
1044
+ handler.unload(cacheTabs[key]);
1045
+ stacks.removeTab(key);
1046
+ }
1047
+ }
1048
+ shouldLoad = true;
1049
+ }
1050
+ else if (currentPage && handler.isTabBar(handler.pathname)) {
1051
+ if (handler.isSamePage(currentPage))
1052
+ return;
1053
+ if (handler.isTabBar(currentPage.path)) {
1054
+ handler.hide(currentPage);
1055
+ stacks.pushTab(currentPage.path.split('?')[0]);
1056
+ }
1057
+ else if (stacks.length > 0) {
1058
+ const firstIns = stacks.getItem(0);
1059
+ if (handler.isTabBar(firstIns.path)) {
1060
+ handler.unload(currentPage, stacks.length - 1);
1061
+ stacks.pushTab(firstIns.path.split('?')[0]);
1062
+ }
1063
+ else {
1064
+ handler.unload(currentPage, stacks.length);
1065
+ }
1066
+ }
1067
+ if (cacheTabs[handler.pathname]) {
1068
+ stacks.popTab(handler.pathname);
1069
+ return handler.show(stacks.getItem(0), pageConfig, 0);
1070
+ }
1071
+ shouldLoad = true;
1072
+ }
1073
+ else if (action === 'POP') {
1006
1074
  // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
1007
1075
  const prevIndex = stacks.getPrevIndex(pathname);
1008
1076
  const delta = stacks.getDelta(pathname);
@@ -1017,38 +1085,40 @@ function createRouter(app, config, framework) {
1017
1085
  }
1018
1086
  }
1019
1087
  }
1020
- else {
1021
- if (handler.isTabBar) {
1022
- if (handler.isSamePage(currentPage))
1023
- return;
1024
- const prevIndex = stacks.getPrevIndex(pathname, 0);
1025
- handler.hide(currentPage);
1026
- if (prevIndex > -1) {
1027
- // NOTE: tabbar 页且之前出现过,直接复用
1028
- return handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1029
- }
1030
- }
1031
- else if (action === 'REPLACE') {
1032
- const delta = stacks.getDelta(pathname);
1033
- // NOTE: 页面路由记录并不会清空,只是移除掉缓存的 stack 以及页面
1034
- handler.unload(currentPage, delta);
1035
- }
1036
- else if (action === 'PUSH') {
1037
- handler.hide(currentPage);
1038
- }
1088
+ else if (action === 'REPLACE') {
1089
+ const delta = stacks.getDelta(pathname);
1090
+ // NOTE: 页面路由记录并不会清空,只是移除掉缓存的 stack 以及页面
1091
+ handler.unload(currentPage, delta);
1092
+ shouldLoad = true;
1093
+ }
1094
+ else if (action === 'PUSH') {
1095
+ handler.hide(currentPage);
1039
1096
  shouldLoad = true;
1040
1097
  }
1041
1098
  if (shouldLoad || stacks.length < 1) {
1042
- const el = (_g = element.default) !== null && _g !== void 0 ? _g : element;
1099
+ const el = (_h = element.default) !== null && _h !== void 0 ? _h : element;
1043
1100
  const loadConfig = Object.assign({}, pageConfig);
1044
1101
  const stacksIndex = stacks.length;
1045
1102
  delete loadConfig['path'];
1046
1103
  delete loadConfig['load'];
1047
- const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(stacksIndex)), {}, loadConfig);
1104
+ let pageStampId = '';
1105
+ if (launchStampId) {
1106
+ pageStampId = launchStampId;
1107
+ launchStampId = '';
1108
+ }
1109
+ else {
1110
+ pageStampId = createStampId();
1111
+ }
1112
+ const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1048
1113
  if (params)
1049
1114
  page.options = params;
1050
- return handler.load(page, pageConfig, stacksIndex);
1115
+ handler.load(page, pageConfig, pageStampId, stacksIndex);
1051
1116
  }
1117
+ runtime.eventCenter.trigger('__afterTaroRouterChange', {
1118
+ toLocation: {
1119
+ path: handler.pathname
1120
+ }
1121
+ });
1052
1122
  });
1053
1123
  const routePath = addLeadingSlash(stripBasename(exports.history.location.pathname, handler.basename));
1054
1124
  if (routePath === '/') {