@ray-js/router-mp
Version:
Ray Core
162 lines (159 loc) • 4.61 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import "core-js/modules/esnext.iterator.constructor.js";
import "core-js/modules/esnext.iterator.find.js";
import "core-js/modules/esnext.iterator.for-each.js";
import "core-js/modules/esnext.iterator.some.js";
import { getLaunchOptionsSync } from '@ray-js/api';
import { url } from '@ray-js/library';
import { RouterScheduler as IRouterScheduler } from '@ray-js/types';
import { compile, match, pathToRegexp } from 'path-to-regexp';
import slash from 'slash';
export function currentPage() {
const pages = getCurrentPages();
if (pages.length > 0) {
return pages[pages.length - 1];
} else {
const {
path,
query
} = getLaunchOptionsSync();
return {
route: path,
options: query
};
}
}
/**
* 小程序路由别名机制,将标准化的 web pathname 转化为小程序的 path
*/
export class RouterScheduler extends IRouterScheduler {
constructor() {
super();
this.$entityMap = [];
this.$subPackageRoute = {};
this.$pathMap = [];
}
getCurrentRoute() {
const {
route,
__pureRoute__,
__scope__
} = currentPage();
let normalizedRoute = __pureRoute__ || route;
// 小程序页面对象上的 route 不是以 / 开头的,需要补上
if (!normalizedRoute.startsWith('/')) {
normalizedRoute = '/' + normalizedRoute;
}
return this.getRouteByPath(normalizedRoute);
}
/**
* 将小程序地址栏转化为 web 地址
* @param opts
*/
getHrefByPath(opts) {
const {
query,
path,
hash = ''
} = opts;
const route = this.matchPageByPath(path);
if (route) {
const keys = [];
pathToRegexp(route.route, keys);
if (keys.length > 0) {
const restQuery = _objectSpread({}, query);
keys.forEach(_ref => {
let {
name
} = _ref;
delete restQuery[name];
});
// 兼容小程序tab页,因tab页不能携带参数
keys.forEach(k => {
var _query$k$name;
return query[k.name] = (_query$k$name = query[k.name]) !== null && _query$k$name !== void 0 ? _query$k$name : '';
});
const href = compile(route.route, {
validate: false
})(query) + hash;
return url.params(href, restQuery);
}
return url.params(route.route + hash, query);
}
return '';
}
registryPages(params) {
const {
routes,
tabBar,
subpackages = []
} = params;
const tabBarList = (tabBar === null || tabBar === void 0 ? void 0 : tabBar.list) || [];
subpackages.forEach(subPackage => {
const root = subPackage.root;
const subPackagesPages = subPackage.routes || subPackage.pages || [];
subPackagesPages.forEach(page => {
this.addSubPackagePage({
root,
route: page.route || page.path,
path: page.path
});
});
});
routes.forEach(r => {
const isTabBar = tabBarList.some(item => r.path === item.pagePath);
const route = r.route || r.path;
this.addPage(_objectSpread(_objectSpread({}, r), {}, {
isTabBar,
route
}));
});
}
getMatchedPage(pathname) {
return this.matchPageByPathname(pathname);
}
getRouteByPath(pagePath) {
return this.$pathMap.find(item => item.path === pagePath);
}
addPage(route) {
this.$entityMap.push(route);
this.$pathMap.push(route);
}
addSubPackagePage(subPackageRoute) {
if (!this.$subPackageRoute[subPackageRoute.root]) {
this.$subPackageRoute[subPackageRoute.root] = [];
}
this.$subPackageRoute[subPackageRoute.root].push(subPackageRoute);
}
getMatchedSubPackagePage(pathname, subPackage) {
const subs = this.$subPackageRoute[subPackage] || [];
for (let index = 0; index < subs.length; index++) {
const item = subs[index];
const urlMatch = match(item.route, {
decode: decodeURIComponent
});
if (urlMatch(pathname)) {
return {
pathname,
route: item.route,
params: urlMatch(pathname)['params'],
subPackage,
path: slash('/' + subPackage + item.path)
};
}
}
}
/**
* 以小程序地址进行匹配页面
* @param path - 小程序页面地址 /pages/home/index
* @returns
*/
matchPageByPath(path) {
const route = this.$pathMap.find(route => route.path === path);
if (!route) {
console.warn('Not match route by:', path);
return undefined;
}
return route;
}
}