修复node包

This commit is contained in:
唐明明
2022-06-15 15:13:01 +08:00
parent a135d6bed4
commit e5207d5b7f
744 changed files with 66977 additions and 1737 deletions

76
node_modules/uni-simple-router/src/H5/buildRouter.ts generated vendored Normal file
View File

@@ -0,0 +1,76 @@
import {RoutesRule, Router, routesMapRule, totalNextRoute, hookToggle, navtoRule} from '../options/base';
import {H5Config} from '../options/config';
import {warn} from '../helpers/warn'
import {getDataType, getRoutePath} from '../helpers/utils'
import { onTriggerEachHook } from '../public/hooks';
export function buildVueRoutes(router: Router, vueRouteMap:RoutesRule):RoutesRule {
const {pathMap, finallyPathList} = (router.routesMap as routesMapRule);
const vueRoutePathList:Array<string> = Object.keys(vueRouteMap);
for (let i = 0; i < vueRoutePathList.length; i++) {
const path = vueRoutePathList[i];
const myRoute:RoutesRule = pathMap[path];
const vueRoute:RoutesRule = vueRouteMap[path];
if (!myRoute) {
warn(`${path} 路由地址在路由表中未找到,确定是否传递漏啦`, router, true);
} else {
const {finallyPath} = getRoutePath(myRoute, router);
if (finallyPath instanceof Array) {
throw new Error(`非 vueRouterDev 模式下alias、aliasPath、path 无法提供数组类型! ${JSON.stringify(myRoute)}`);
}
if (myRoute.name != null) {
vueRoute.name = myRoute.name;
}
const vuePath = vueRoute['path'];
const vueAlias = vueRoute['alias'];
delete vueRoute['alias'];
vueRoute['path'] = (finallyPath as string);
if (vuePath === '/' && vueAlias != null) {
vueRoute['alias'] = vueAlias;
vueRoute['path'] = vuePath;
}
const beforeEnter = myRoute.beforeEnter;
if (beforeEnter) {
vueRoute['beforeEnter'] = function(
to:totalNextRoute,
from: totalNextRoute,
next:(rule?: navtoRule|false)=>void,
):void{
onTriggerEachHook(to, from, router, hookToggle['enterHooks'], next)
};
}
}
}
if (finallyPathList.includes('*')) {
vueRouteMap['*'] = pathMap['*']
}
return vueRouteMap
}
export function buildVueRouter(router:Router, vueRouter:any, vueRouteMap:RoutesRule|RoutesRule[]) :void |never {
let routes:RoutesRule[] = [];
if (getDataType<RoutesRule|RoutesRule[]>(vueRouteMap) === '[object Array]') {
routes = (vueRouteMap as RoutesRule[]);
} else {
routes = Object.values(vueRouteMap);
}
const {scrollBehavior, fallback} = router.options.h5 as H5Config;
const oldScrollBehavior = vueRouter.options.scrollBehavior;
vueRouter.options.scrollBehavior = function proxyScrollBehavior(
to:totalNextRoute,
from:totalNextRoute,
savedPosition:any
) {
oldScrollBehavior && oldScrollBehavior(to, from, savedPosition);
return (scrollBehavior as Function)(to, from, savedPosition)
}
vueRouter.fallback = fallback;
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
const newVueRouter:any = new vueRouter.constructor({
...router.options.h5,
base: vueRouter.options.base,
mode: vueRouter.options.mode,
routes
});
vueRouter.matcher = newVueRouter.matcher;
}

32
node_modules/uni-simple-router/src/H5/patch.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import { removeSimpleValue } from '../helpers/utils';
import { Router} from '../options/base';
let [dynamicCacheName, __id__] = ['', ''];
export const addKeepAliveInclude = function(
router:Router
):void{
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/316 2021年12月10日14:30:13
const app = getApp();
const keepAliveInclude:Array<string> = app.keepAliveInclude;
if (router.runId === 0 && keepAliveInclude.length === 0) {
__id__ = app.$route.params.__id__;
dynamicCacheName = app.$route.meta.name;
const cacheId = dynamicCacheName + '-' + __id__;
app.keepAliveInclude.push(cacheId)
} else {
if (dynamicCacheName !== '') {
const arrayCacheId = app.keepAliveInclude;
for (let i = 0; i < arrayCacheId.length; i++) {
const cacheId:string = arrayCacheId[i];
const cacheIdReg = new RegExp(`${dynamicCacheName}-(\\d+)$`);
const firstCacheId = `${dynamicCacheName}-${__id__}`;
if (cacheIdReg.test(cacheId) && cacheId !== firstCacheId) {
removeSimpleValue(arrayCacheId, firstCacheId);
dynamicCacheName = '';
break;
}
}
}
}
}

71
node_modules/uni-simple-router/src/H5/proxyHook.ts generated vendored Normal file
View File

@@ -0,0 +1,71 @@
import {Router, proxyHookName, totalNextRoute, navtoRule} from '../options/base';
export class MyArray extends Array {
constructor(
private router:Router,
private vueEachArray:Array<Function>,
private myEachHook:Function,
private hookName:'beforeHooks'| 'afterHooks',
) {
super();
Object.setPrototypeOf(this, MyArray.prototype)
}
push(v:any):any {
this.vueEachArray.push(v);
const index = this.length;
this[this.length] = (to: totalNextRoute, from: totalNextRoute, next:(rule?: navtoRule|false)=>void) => {
if (index > 0) {
this.vueEachArray[index](to, from, () => {
next && next()
});
} else {
this.myEachHook(to, from, (nextTo?:navtoRule|false) => {
// Fixe https://github.com/SilurianYang/uni-simple-router/issues/241 2021年3月6日22:15:27
// 目前不调用uni-app的守卫函数因为会丢失页面栈信息
if (nextTo === false) {
next(false);
} else {
this.vueEachArray[index](to, from, (uniNextTo?:navtoRule|false) => {
next(nextTo);
})
}
}, this.router, true);
}
};
}
}
export function proxyEachHook(router:Router, vueRouter:any):void {
const hookList:Array<'beforeHooks'| 'afterHooks'> = ['beforeHooks', 'afterHooks'];
for (let i = 0; i < hookList.length; i++) {
const hookName = hookList[i];
const myEachHook = router.lifeCycle[(hookName as proxyHookName)][0];
if (myEachHook) {
const vueEachArray:Array<Function> = vueRouter[hookName];
vueRouter[hookName] = new MyArray(router, vueEachArray, myEachHook, hookName);
}
}
}
export function proxyH5Mount(router:Router):void {
if (router.mount.length === 0) {
if (router.options.h5?.vueRouterDev) {
return
}
const uAgent = navigator.userAgent;
const isIos = !!uAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
if (isIos) {
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/109
setTimeout(() => {
const element = document.getElementsByTagName('uni-page');
if (element.length > 0) {
return false
}
window.location.reload();
}, 0);
}
} else {
const [{app}] = router.mount;
app.$mount();
router.mount = [];
}
}

98
node_modules/uni-simple-router/src/app/appPatch.ts generated vendored Normal file
View File

@@ -0,0 +1,98 @@
import { navtoRule, objectAny, Router, totalNextRoute } from '../options/base';
import { AppConfig } from '../options/config';
let quitBefore:number|null = null;
let TABBAR:objectAny|null = null;
export function registerLoddingPage(
router:Router,
):void{
if (router.options.APP?.registerLoadingPage) {
const { loadingPageHook, loadingPageStyle } = router.options.APP as AppConfig; // 获取app所有配置
const view = new plus.nativeObj.View('router-loadding', {
top: '0px',
left: '0px',
height: '100%',
width: '100%',
...(loadingPageStyle as Function)()
});
(loadingPageHook as Function)(view); // 触发等待页面生命周期
}
}
export function runtimeQuit(
title:string|undefined = '再按一次退出应用'
):void{
const nowTime = +new Date();
if (!quitBefore) {
quitBefore = nowTime;
uni.showToast({
title,
icon: 'none',
position: 'bottom',
duration: 1000
});
setTimeout(() => { quitBefore = null }, 1000);
} else {
if (nowTime - quitBefore < 1000) {
plus.runtime.quit();
}
}
}
export function HomeNvueSwitchTab(
router:Router,
to:navtoRule,
oldMethod:Function
):Promise<Boolean> {
return new Promise((
resolve:(value:boolean)=>void
) => {
if (router.runId !== 0) {
return resolve(false)
}
if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) {
return resolve(false)
}
// Fixe https://github.com/SilurianYang/uni-simple-router/issues/373 2022-4-3 19:40:59
oldMethod({
url: __uniConfig.entryPagePath,
animationDuration:0,
complete: () => resolve(true)
});
})
}
export function tabIndexSelect(
to:totalNextRoute,
from:totalNextRoute
):boolean {
if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) {
return false
}
const tabBarList = __uniConfig.tabBar.list;
const routes:Array<totalNextRoute> = [];
let activeIndex:number = 0;
for (let i = 0; i < tabBarList.length; i++) {
const route:totalNextRoute = tabBarList[i];
if ('/' + route.pagePath === to.path || '/' + route.pagePath === from.path) {
if (route.pagePath === from.path) {
activeIndex = i;
}
routes.push(route);
}
if (routes.length === 2) {
break
}
}
if (routes.length !== 2) {
return false
}
if (TABBAR == null) {
TABBAR = uni.requireNativePlugin('uni-tabview')
}
(TABBAR as objectAny).switchSelect({
index: activeIndex
})
return true
}

View File

@@ -0,0 +1,18 @@
import { Router} from '../options/base';
export function getEnterPath(
vueVim:any,
router:Router,
) :string {
switch (router.options.platform) {
case 'mp-alipay':
case 'mp-weixin':
case 'mp-toutiao':
case 'mp-qq':
return vueVim.$options.mpInstance.route;
case 'mp-baidu':
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/251
return vueVim.$options.mpInstance.is || vueVim.$options.mpInstance.pageinstance.route;
}
return vueVim.$options.mpInstance.route; // 这是暂时的 因为除了以上的小程序 其他没测试 先这样写
}

85
node_modules/uni-simple-router/src/component/link.vue generated vendored Normal file
View File

@@ -0,0 +1,85 @@
<template>
<view @click="gotoPage()"><slot></slot></view>
</template>
<script>
const navType = {
push: 'push',
replace: 'replace',
replaceAll: 'replaceAll',
pushTab: 'pushTab',
back:'back'
};
export default {
props: {
to: {
type: [String, Object],
required: true
},
stopNavto: {
type: Boolean,
default: false,
},
navType: {
type: String,
default: 'push',
},
level: {
type: Number,
default: 1,
},
append: {
type: Boolean,
default: false,
},
},
methods: {
formatNav(text) {
if (text != null && text.constructor === String) {
const keyArray = [];
text = text.replace(/((\w+)|('\s*(\w+)\s*')|("\s*(\w+)\s*"))\s*(?=:)/g, function (val) {
const key = `"${val.trim().replace(/"|'/g, '')}"`;
keyArray.push(key);
return key
});
const removeReg=/('|")/g;
for (let i = 0; i < keyArray.length; i++) {
const key = keyArray[i];
text=text.replace(new RegExp(`${key}\\s*:\\s*('[^']+')`, 'g'),(...args)=>{
const $1=args[1];
return `${key}:"${$1.replace(removeReg,'')}"`
})
}
try {
text=JSON.parse(text);
} catch (error) {}
}
if (this.append) {
let pathArr = this.$Route.path.split('/');
pathArr.splice(pathArr.length - this.level, this.level);
pathArr = pathArr.join('/');
if (text.constructor === Object) {
if (text.path) {
text.path = pathArr + text.path;
}
} else {
text = pathArr + text;
}
}
return text;
},
gotoPage() {
if (this.stopNavto) {
return true;
}
const type = navType[this.navType];
if (type == null) {
return console.error(` "navType" unknown type \n\n value${Object.values(navType).join('、')}`);
}
const navInfo = this.formatNav(this.to);
this.$Router[type](navInfo);
},
},
};
</script>

9
node_modules/uni-simple-router/src/global.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
declare var uni:any;
declare var plus:any;
declare var __uniConfig:any;
declare var __uniRoutes:any;
declare function getCurrentPages(isAll:boolean|undefined=false):any;
declare function getApp(args?:{allowDefault: true}):any;
declare var $npm_package_name:string;
declare var $npm_package_version:string;
declare var $npm_package_last_version:string;

84
node_modules/uni-simple-router/src/helpers/config.ts generated vendored Normal file
View File

@@ -0,0 +1,84 @@
import {err} from './warn'
import { InstantiateConfig, LifeCycleConfig} from '../options/config'
import { vueHookNameRule, proxyDepsRule } from '../options/base';
import { parseQuery } from '../public/query';
export const mpPlatformReg = '(^mp-weixin$)|(^mp-baidu$)|(^mp-alipay$)|(^mp-toutiao$)|(^mp-qq$)|(^mp-360$)' // 小程序下不能直接导出正则 需要重新组装成正则 不然bug一推 诡异
export const baseConfig:InstantiateConfig = {
h5: {
paramsToQuery: false,
vueRouterDev: false,
vueNext: false,
mode: 'hash',
base: '/',
linkActiveClass: 'router-link-active',
linkExactActiveClass: 'router-link-exact-active',
scrollBehavior: (to:any, from:any, savedPostion:Function) => ({ x: 0, y: 0 }),
fallback: true
},
APP: {
registerLoadingPage: true,
loadingPageStyle: () => JSON.parse('{"backgroundColor":"#FFF"}'),
loadingPageHook: (view:any) => { view.show(); },
launchedHook: () => { plus.navigator.closeSplashscreen(); },
animation: {}
},
applet: {
animationDuration: 300
},
beforeProxyHooks: {
onLoad: ([options], next, router) => {
next([parseQuery({query: options}, router)])
}
},
platform: 'h5',
keepUniOriginNav: false,
debugger: false,
routerBeforeEach: (to, from, next) => { next() },
routerAfterEach: (to, from) => {},
routerErrorEach: (error, router) => { router.$lockStatus = false; err(error, router, true); },
detectBeforeLock: (router, to, navType) => {},
routes: [
{
path: '/choose-location'
},
{
path: '/open-location'
},
{
path: '/preview-image'
}
]
}
export const lifeCycle:LifeCycleConfig = {
beforeHooks: [],
afterHooks: [],
routerBeforeHooks: [],
routerAfterHooks: [],
routerErrorHooks: []
};
export const proxyHookDeps:proxyDepsRule = {
resetIndex: [], // 还原时执行的生命周期的索引
hooks: {},
options: {}
}
export const proxyHookName:Array<vueHookNameRule> = [
'onLaunch',
'onShow',
'onHide',
'onError',
'onInit',
'onLoad',
'onReady',
'onUnload',
'onResize',
'created',
'beforeMount',
'mounted',
'beforeDestroy',
'destroyed'
]

View File

@@ -0,0 +1,47 @@
import {RoutesRule, Router, routesMapRule} from '../options/base';
import {H5Config} from '../options/config';
import {warn} from './warn'
import {getRoutePath} from './utils'
export function createRouteMap(
router: Router,
routes: RoutesRule[],
): routesMapRule|never {
const routesMap:routesMapRule = {
finallyPathList: [],
finallyPathMap: Object.create(null),
aliasPathMap: Object.create(null),
pathMap: Object.create(null),
vueRouteMap: Object.create(null),
nameMap: Object.create(null)
}
routes.forEach(route => {
const { finallyPath, aliasPath, path} = getRoutePath(route, router);
if (path == null) {
throw new Error(`请提供一个完整的路由对象,包括以绝对路径开始的 path 字符串 ${JSON.stringify(route)}`);
}
if (finallyPath instanceof Array) {
if (!(router.options.h5 as H5Config).vueRouterDev && router.options.platform === 'h5') {
throw new Error(`非 vueRouterDev 模式下route.alias 目前无法提供数组类型! ${JSON.stringify(route)}`);
}
}
const strFinallyPath = (finallyPath as string);
const strAliasPath = (aliasPath as string);
if (router.options.platform !== 'h5') {
if (strFinallyPath.indexOf('/') !== 0 && path !== '*') {
warn(`当前路由对象下route${JSON.stringify(route)} 是否缺少了前缀 /`, router, true);
}
}
if (!routesMap.finallyPathMap[strFinallyPath]) {
routesMap.finallyPathMap[strFinallyPath] = route;
routesMap.aliasPathMap[strAliasPath] = route;
routesMap.pathMap[path] = route;
routesMap.finallyPathList.push(strFinallyPath);
if (route.name != null) {
routesMap.nameMap[route.name] = route;
}
}
})
return routesMap;
}

View File

@@ -0,0 +1,36 @@
import { navtoRule, navErrorRule, Router, proxyHookName, guardHookRule, totalNextRoute, hookToggle} from '../options/base';
import { LifeCycleConfig, InstantiateConfig} from '../options/config';
import {onTriggerEachHook} from '../public/hooks'
export function registerHook(list:Array<Function>, fn:Function):void {
list[0] = fn;
}
export function registerRouterHooks<T extends LifeCycleConfig>(cycleHooks:T, options:InstantiateConfig):T {
registerHook(cycleHooks.routerBeforeHooks, function(to:totalNextRoute, from: totalNextRoute, next:(rule?: navtoRule|false)=>void):void {
(options.routerBeforeEach as Function)(to, from, next);
})
registerHook(cycleHooks.routerAfterHooks, function(to:totalNextRoute, from: totalNextRoute):void {
(options.routerAfterEach as Function)(to, from);
})
registerHook(cycleHooks.routerErrorHooks, function(error:navErrorRule, router:Router):void {
(options.routerErrorEach as Function)(error, router);
})
return cycleHooks;
}
export function registerEachHooks(router:Router, hookType:proxyHookName, userGuard:guardHookRule) {
registerHook(router.lifeCycle[hookType], function(
to:totalNextRoute,
from: totalNextRoute,
next:(rule?: navtoRule|false)=>void,
router:Router,
auto:boolean,
):void {
if (auto) { // h5端 vue-router自动触发 非自己调用触发
onTriggerEachHook(to, from, router, hookToggle[hookType], next)
} else {
userGuard(to, from, next)
}
})
}

114
node_modules/uni-simple-router/src/helpers/mixins.ts generated vendored Normal file
View File

@@ -0,0 +1,114 @@
import { Router, routesMapRule, RoutesRule, pageTypeRule} from '../options/base';
import {createRouteMap} from '../helpers/createRouteMap'
import {buildVueRoutes, buildVueRouter} from '../H5/buildRouter'
import {proxyEachHook} from '../H5/proxyHook'
import {registerLoddingPage} from '../app/appPatch';
import { proxyPageHook } from '../public/page';
import { forceGuardEach } from '../public/methods';
import { assertParentChild, voidFun } from './utils';
import { getEnterPath } from '../applets/appletPatch';
import { mpPlatformReg } from './config';
import {beforeProxyHook} from '../public/beforeProxyHook'
let registerRouter:boolean = false;
let onloadProxyOk:boolean = false;
const appletProxy:{
app:boolean;
page:string;
} = {
app: false,
page: ''
}
export function getMixins(Vue:any, router: Router):{
beforeCreate(this: any): void;
} | {
beforeCreate(): void;
} | {
onLaunch(): void;
} {
let platform = router.options.platform;
if (new RegExp(mpPlatformReg, 'g').test(platform)) {
platform = 'app-lets';
}
const toggleHooks = {
h5: {
beforeCreate(this: any): void {
beforeProxyHook(this, router);
if (this.$options.router) {
router.$route = this.$options.router; // 挂载vue-router到路由对象下
let vueRouteMap:RoutesRule[]|RoutesRule = [];
if (router.options.h5?.vueRouterDev) {
vueRouteMap = router.options.routes;
} else {
vueRouteMap = createRouteMap(router, this.$options.router.options.routes).finallyPathMap;
(router.routesMap as routesMapRule).vueRouteMap = vueRouteMap;
buildVueRoutes(router, vueRouteMap);
}
buildVueRouter(router, this.$options.router, vueRouteMap);
proxyEachHook(router, this.$options.router);
}
}
},
'app-plus': {
beforeCreate(this: any): void {
beforeProxyHook(this, router);
if (!registerRouter) {
registerRouter = true;
proxyPageHook(this, router, 'app');
registerLoddingPage(router);
}
}
},
'app-lets': {
beforeCreate(this: any): void {
beforeProxyHook(this, router);
// 保证这个函数不会被重写
const pluginMark = $npm_package_name;
voidFun(pluginMark);
let isProxy:boolean = true;
const pageType:pageTypeRule = this.$options.mpType;
if (onloadProxyOk) {
return
}
if (pageType === 'component') {
isProxy = assertParentChild(appletProxy['page'], this);
} else {
if (pageType === 'page') {
appletProxy[pageType] = getEnterPath(this, router);
router.enterPath = appletProxy[pageType]; // 我不确定在不同端是否都是同样的变现?可能有的为非绝对路径?
} else {
appletProxy[pageType] = true;
}
}
if (isProxy) {
proxyPageHook(this, router, pageType);
}
},
onLoad(this: any):void{
// 保证这个函数不会被重写否则必须在启动页写onLoad
const pluginMark = $npm_package_name;
voidFun(pluginMark);
if (!onloadProxyOk && assertParentChild(appletProxy['page'], this)) {
onloadProxyOk = true;
forceGuardEach(router);
}
}
}
};
return toggleHooks[(platform as 'h5'|'app-plus'|'app-lets')];
}
export function initMixins(Vue: any, router: Router) {
const routesMap = createRouteMap(router, router.options.routes);
router.routesMap = routesMap; // 挂载自身路由表到路由对象下
// Vue.util.defineReactive(router, '_Route', createRoute(router, 19970806))
Vue.mixin({
...getMixins(Vue, router)
});
}

466
node_modules/uni-simple-router/src/helpers/utils.ts generated vendored Normal file
View File

@@ -0,0 +1,466 @@
import {H5Config, InstantiateConfig} from '../options/config';
import {RoutesRule, routesMapRule, routesMapKeysRule, Router, totalNextRoute, objectAny, navErrorRule, NAVTYPE, navRoute, uniBackApiRule, uniBackRule} from '../options/base';
import {baseConfig} from '../helpers/config';
import {ERRORHOOK} from '../public/hooks'
import {warnLock} from '../helpers/warn'
import { createRoute, navjump } from '../public/methods';
const Regexp = require('path-to-regexp');
export function voidFun(...args:any):void{}
export function def(
defObject:objectAny,
key:string,
getValue:Function
) {
Object.defineProperty(defObject, key, {
get() {
return getValue();
}
})
}
export function timeOut(time:number):Promise<void> {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, time)
})
}
export function mergeConfig<T extends InstantiateConfig>(baseConfig: T, userConfig: T): T {
const config: {[key: string]: any} = Object.create(null);
const baseConfigKeys: Array<string> = Object.keys(baseConfig).concat(['resolveQuery', 'parseQuery']);
for (let i = 0; i < baseConfigKeys.length; i += 1) {
const key = baseConfigKeys[i];
if (userConfig[key] != null) {
if (userConfig[key].constructor === Object) {
config[key] = {
...baseConfig[key],
...userConfig[key]
};
} else if (key === 'routes') {
config[key] = [
...baseConfig[key],
...userConfig[key]
];
} else {
config[key] = userConfig[key];
}
} else {
config[key] = baseConfig[key];
}
}
return config as T;
}
export function notDeepClearNull<T>(object:T):T {
for (const key in object) {
if (object[key] == null) {
delete object[key];
}
}
return object;
}
export function getRoutePath(route: RoutesRule, router:Router): {
finallyPath: string | string[];
aliasPath: string;
path: string;
alias: string | string[] | undefined;
} {
let finallyPath = route.aliasPath || route.alias || route.path;
if (router.options.platform !== 'h5') {
finallyPath = route.path
}
return {
finallyPath,
aliasPath: route.aliasPath || route.path,
path: route.path,
alias: route.alias
}
}
export function assertNewOptions<T extends InstantiateConfig>(
options: T
): T | never {
const {platform, routes} = options;
if (platform == null) {
throw new Error(`你在实例化路由时必须传递 'platform'`);
}
if (routes == null || routes.length === 0) {
throw new Error(`你在实例化路由时必须传递 routes 为空,这是无意义的。`);
}
if (options.platform === 'h5') {
if (options.h5?.vueRouterDev) {
baseConfig.routes = [];
}
}
const mergeOptions = mergeConfig<T>(baseConfig as T, options);
return mergeOptions;
}
export function getWildcardRule(
router:Router,
msg?:navErrorRule
):RoutesRule|never {
const routesMap = (router.routesMap as routesMapRule);
const route = routesMap.finallyPathMap['*'];
if (route) { // 有写通配符
return route
}
if (msg) {
ERRORHOOK[0](msg, router);
}
throw new Error(`当前路由表匹配规则已全部匹配完成,未找到满足的匹配规则。你可以使用 '*' 通配符捕捉最后的异常`);
}
export function notRouteTo404(
router:Router,
toRoute:RoutesRule|{
redirect:any;
path:string
},
parseToRule:totalNextRoute,
navType:NAVTYPE
):RoutesRule|totalNextRoute|never {
if (toRoute.path !== '*') { // 不是通配符 正常匹配成功
return (toRoute as RoutesRule);
}
const redirect = toRoute.redirect;
if (typeof redirect === 'undefined') {
throw new Error(` * 通配符必须配合 redirect 使用。redirect: string | Location | Function`);
}
let newRoute = redirect;
if (typeof newRoute === 'function') {
newRoute = newRoute(parseToRule) as totalNextRoute;
}
const redirectRule = navjump(newRoute as totalNextRoute, router, navType, undefined, undefined, undefined, false);
return (redirectRule as totalNextRoute);
}
export function routesForMapRoute(
router: Router,
path: string,
mapArrayKey:Array<routesMapKeysRule>,
deepFind:boolean|undefined = false
):RoutesRule|never {
if (router.options.h5?.vueRouterDev) {
return {path}
}
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/252
const startPath = path.split('?')[0];
let wildcard = '';
const routesMap = (router.routesMap as routesMapRule);
for (let i = 0; i < mapArrayKey.length; i++) {
const mapKey = mapArrayKey[i];
const mapList = routesMap[mapKey];
for (const [key, value] of Object.entries(mapList)) {
if (key === '*') {
if (wildcard === '') {
wildcard = '*'
}
continue;
}
const route:string|RoutesRule = value;
let rule:string = key;
if (getDataType<Array<string>|objectAny>(mapList) === '[object Array]') {
rule = (route as string);
}
const pathRule:RegExp = Regexp(rule);
const result = pathRule.exec(startPath);
if (result != null) {
if (getDataType<string|RoutesRule>(route) === '[object String]') {
return routesMap.finallyPathMap[(route as string)];
}
return (route as RoutesRule);
}
}
}
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/302 2021-8-4 16:38:44
if (deepFind) {
return ({} as RoutesRule);
}
if (routesMap['aliasPathMap']) {
const results = routesForMapRoute(router, path, ['aliasPathMap'], true);
if (Object.keys(results).length > 0) {
return results;
}
}
if (wildcard !== '') {
return getWildcardRule(router);
}
throw new Error(`${path} 路径无法在路由表中找到!检查跳转路径及路由表`);
}
export function getDataType<T>(data:T):string {
return Object.prototype.toString.call(data)
}
export function copyData<T>(object:T): T {
return JSON.parse(JSON.stringify(object))
}
export function removeSimpleValue(
array:Array<string|number>,
value:string
):Boolean {
for (let i = 0; i < array.length; i++) {
const it = array[i];
if (it === value) {
array.splice(i, 1);
return true
}
}
return false
}
export function getUniCachePage<T extends objectAny>(pageIndex?:number):T|[] {
const pages:T = getCurrentPages();
if (pageIndex == null) {
return pages
}
if (pages.length === 0) {
return pages;
}
const page = pages.reverse()[pageIndex];
if (page == null) {
return []
}
return page;
}
export function urlToJson(url :string):{
path:string;
query:objectAny
} {
const query:objectAny = {};
const [path, params] = url.split('?');
if (params != null) {
const parr = params.split('&');
for (const i of parr) {
const arr = i.split('=');
query[arr[0]] = arr[1];
}
}
return {
path,
query
}
}
export function forMatNextToFrom<T extends totalNextRoute>(
router:Router,
to:T,
from:T
):{
matTo:T;
matFrom: T;
} {
let [matTo, matFrom] = [to, from];
if (router.options.platform === 'h5') {
const {vueNext, vueRouterDev} = (router.options.h5 as H5Config);
if (!vueNext && !vueRouterDev) {
matTo = createRoute(router, undefined, matTo) as T;
matFrom = createRoute(router, undefined, matFrom) as T;
}
} else {
matTo = createRoute(router, undefined, deepClone<T>(matTo)) as T;
matFrom = createRoute(router, undefined, deepClone<T>(matFrom)) as T;
}
return {
matTo: matTo,
matFrom: matFrom
}
}
export function paramsToQuery(
router:Router,
toRule:totalNextRoute|string
):totalNextRoute|string {
if (router.options.platform === 'h5' && !router.options.h5?.paramsToQuery) {
return toRule;
}
if (getDataType<totalNextRoute|string>(toRule) === '[object Object]') {
const {name, params, ...moreToRule} = (toRule as totalNextRoute);
let paramsQuery = params;
if (router.options.platform !== 'h5' && paramsQuery == null) {
paramsQuery = {};
}
if (name != null && paramsQuery != null) {
let route = (router.routesMap as routesMapRule).nameMap[name];
if (route == null) {
route = getWildcardRule(router, { type: 2, msg: `命名路由为:${name} 的路由,无法在路由表中找到!`, toRule});
}
const {finallyPath} = getRoutePath(route, router);
if (finallyPath.includes(':')) { // 动态路由无法使用 paramsToQuery
ERRORHOOK[0]({ type: 2, msg: `动态路由:${finallyPath} 无法使用 paramsToQuery`, toRule}, router);
} else {
return {
...moreToRule,
path: finallyPath as string,
query: paramsQuery
}
}
}
}
return toRule
}
export function assertDeepObject(object:objectAny):boolean {
let arrMark = null;
try {
arrMark = JSON.stringify(object).match(/\{|\[|\}|\]/g);
} catch (error) {
warnLock(`传递的参数解析对象失败。` + error)
}
if (arrMark == null) {
return false
}
if (arrMark.length > 3) {
return true;
}
return false
}
export function baseClone<
T extends {
[key:string]:any
}, K extends keyof T
>(
source:T,
target:Array<any>|objectAny
):Array<any>|objectAny|null {
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/292
// 小程序会将null解析为字符串 undefined 建议不要在参数中传递 null
if (source == null) {
target = source;
} else {
for (const key of Object.keys(source)) {
const dyKey = key as T[K];
if (source[key] === source) continue
if (typeof source[key] === 'object') {
target[dyKey] = getDataType<T>(source[key]) === '[object Array]' ? ([] as Array<any>) : ({} as objectAny)
target[dyKey] = baseClone(source[key], target[dyKey])
} else {
target[dyKey] = source[key]
}
}
}
return target;
}
export function deepClone<T>(source:T):T {
const __ob__ = getDataType<T>(source) === '[object Array]' ? ([] as Array<any>) : ({} as objectAny);
baseClone(source, __ob__)
return __ob__ as T
}
export function lockDetectWarn(
router:Router,
to:string|number|totalNextRoute|navRoute,
navType:NAVTYPE,
next:Function,
uniActualData:uniBackApiRule|uniBackRule|undefined = {},
passiveType?:'beforeHooks'| 'afterHooks'
):void{
if (passiveType === 'afterHooks') {
next();
} else {
const {detectBeforeLock} = router.options;
detectBeforeLock && detectBeforeLock(router, to, navType);
if (router.$lockStatus) {
(router.options.routerErrorEach as (error: navErrorRule, router:Router) => void)({
type: 2,
msg: '当前页面正在处于跳转状态,请稍后再进行跳转....',
NAVTYPE: navType,
uniActualData
}, router);
} else {
next();
}
}
}
export function assertParentChild(
parentPath:string,
vueVim:any,
):boolean {
while (vueVim.$parent != null) {
const mpPage = vueVim.$parent.$mp;
if (mpPage.page && mpPage.page.is === parentPath) {
return true;
}
vueVim = vueVim.$parent;
}
try {
if (vueVim.$mp.page.is === parentPath || vueVim.$mp.page.route === parentPath) {
return true
}
} catch (error) {
return false
}
return false
}
export function resolveAbsolutePath(
path:string,
router:Router
):string|never {
const reg = /^\/?([^\?\s]+)(\?.+)?$/;
const trimPath = path.trim();
if (!reg.test(trimPath)) {
throw new Error(`${path}】 路径错误,请提供完整的路径(10001)。`);
}
const paramsArray = trimPath.match(reg);
if (paramsArray == null) {
throw new Error(`${path}】 路径错误,请提供完整的路径(10002)。`);
}
const query:string = paramsArray[2] || '';
if (/^\.\/[^\.]+/.test(trimPath)) { // 当前路径下
const navPath:string = (router as unknown as {currentRoute:{path:string}}).currentRoute.path + path;
return navPath.replace(/[^\/]+\.\//, '');
}
const relative = paramsArray[1].replace(/\//g, `\\/`).replace(/\.\./g, `[^\\/]+`).replace(/\./g, '\\.');
const relativeReg = new RegExp(`^\\/${relative}$`);
const route = router.options.routes.filter(it => relativeReg.test(it.path));
if (route.length !== 1) {
throw new Error(`${path}】 路径错误,尝试转成绝对路径失败,请手动转成绝对路径(10003)。`);
}
return route[0].path + query;
}
export function deepDecodeQuery(
query:objectAny
):objectAny {
const formatQuery:objectAny = getDataType<objectAny>(query) === '[object Array]' ? [] : {};
const keys = Object.keys(query);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const it = query[key];
if (typeof it === 'string') {
try {
let json = JSON.parse(decodeURIComponent(it));
if (typeof json !== 'object') {
json = it;
}
formatQuery[key] = json;
} catch (error) {
try {
formatQuery[key] = decodeURIComponent(it)
} catch (error) {
formatQuery[key] = it
}
}
} else if (typeof it === 'object') {
const childQuery = deepDecodeQuery(it);
formatQuery[key] = childQuery
} else {
formatQuery[key] = it
}
}
return formatQuery
}

37
node_modules/uni-simple-router/src/helpers/warn.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
import {debuggerConfig, debuggerArrayConfig} from '../options/config'
import {Router} from '../options/base'
type callType='error'|'warn'|'log';
export function isLog(type:callType, dev:debuggerConfig, errText:any, enforce:boolean = false):boolean {
if (!enforce) {
const isObject = dev.toString() === '[object Object]';
if (dev === false) {
return false
} else if (isObject) {
if ((dev as debuggerArrayConfig)[type] === false) {
return false;
}
}
}
console[type](errText);
return true;
}
export function err(errText:any, router:Router, enforce?:boolean):void {
const dev = (router.options.debugger as debuggerConfig);
isLog('error', dev, errText, enforce);
}
export function warn(errText:any, router:Router, enforce?:boolean):void {
const dev = (router.options.debugger as debuggerConfig);
isLog('warn', dev, errText, enforce);
}
export function log(errText:any, router:Router, enforce?:boolean):void {
const dev = (router.options.debugger as debuggerConfig);
isLog('log', dev, errText, enforce);
}
export function warnLock(errText:any):void {
console.warn(errText);
}

17
node_modules/uni-simple-router/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
export * from './options/base'
export * from './options/config'
export * from './helpers/utils'
export {
runtimeQuit
} from './app/appPatch'
export {
RouterMount,
createRouter
} from './public/router'
const version = $npm_package_version;
if (/[A-Z]/g.test(version)) {
console.warn(`${$npm_package_name.toLocaleLowerCase()} 提示】:当前版本 ${version.toLocaleLowerCase()} 此版本为测试版。有BUG请退回正式版线上正式版本${$npm_package_last_version}`)
}

245
node_modules/uni-simple-router/src/options/base.ts generated vendored Normal file
View File

@@ -0,0 +1,245 @@
import {InstantiateConfig, LifeCycleConfig} from '../options/config';
export enum hookToggle{
'beforeHooks'='beforeEach',
'afterHooks'='afterEach',
'enterHooks'='beforeEnter'
}
export enum navtypeToggle{
'push'='navigateTo',
'replace'='redirectTo',
'replaceAll'='reLaunch',
'pushTab'='switchTab',
'back'='navigateBack'
}
export enum rewriteMethodToggle{
'navigateTo'='push',
'navigate'='push',
'redirectTo'='replace',
'reLaunch'='replaceAll',
'switchTab'='pushTab',
'navigateBack'='back',
}
export type proxyDepsRule={
resetIndex:Array<number>;
hooks: {
[key: number]:{
proxyHook:()=>void;
callHook:(enterPath:string)=>void;
resetHook: ()=>void
}
};
options: {[key: number]: Array<any>;};
};
export type backTypeRule='backbutton'|'navigateBack'
export type pageTypeRule='app'|'page'|'component';
export type vueHookNameRule='onLaunch'|'onShow'|'onHide'|'onError'|'onInit'|'onLoad'|'onReady'|'onUnload'|'onResize'|'created'|'beforeMount'|'mounted'|'beforeDestroy'|'destroyed'
export type reNavMethodRule='navigateTo'|'redirectTo'|'reLaunch'|'switchTab';
export type reNotNavMethodRule='navigateBack';
export type reloadNavRule=totalNextRoute | false | undefined|string;
export type hookListRule=Array<(router:Router, to:totalNextRoute, from: totalNextRoute, toRoute:RoutesRule,next:Function)=>void>
export type guardHookRule=(to: totalNextRoute, from: totalNextRoute, next:(rule?: navtoRule|false)=>void)=>void;
export type navRuleStatus= 0|1|2|3; //0: next(false) 1:next(unknownType) 2:加锁状态,禁止跳转 3:在获取页面栈的时候页面栈不够level获取
export type proxyHookName='beforeHooks'|'afterHooks';
export type navMethodRule = Promise<void | undefined | navRuleStatus>;
export type objectAny={[propName: string]: any;};
export type NAVTYPE = 'push' | 'replace' | 'replaceAll' | 'pushTab'|'back';
export type startAnimationType =
| 'slide-in-right'
| 'slide-in-left'
| 'slide-in-top'
| 'slide-in-bottom'
| 'pop-in'
| 'fade-in'
| 'zoom-out'
| 'zoom-fade-out'
| 'none';
export type endAnimationType =
| 'slide-out-right'
| 'slide-out-left'
| 'slide-out-top'
| 'slide-out-bottom'
| 'pop-out'
| 'fade-out'
| 'zoom-in'
| 'zoom-fade-in'
| 'none';
export type vueOptionRule = {
[propName in vueHookNameRule]: Array<Function> | undefined;
};
// 跳转api时传递的跳转规则
export interface navtoRule {
NAVTYPE?: NAVTYPE; // 跳转类型 v1.1.0+
path?: string; // 跳转路径 绝对路径
name?: string | undefined; // 跳转路径名称
query?: objectAny; // 跳转使用path时 query包含需要传递的参数
params?: objectAny; // 跳转使用name时 params包含需要传递的参数
animationType?: startAnimationType|endAnimationType;
animationDuration?: number;
events?: objectAny;
success?: Function;
fail?: Function;
complete?: Function;
}
// h5 next管道函数中传递的from及to对象
export interface h5NextRule {
fullPath?: string | undefined;
hash?: string | undefined;
matched?: Array<object>;
meta?: object;
name?: undefined | string;
type?: undefined | string;
}
export interface totalNextRoute extends h5NextRule, navtoRule {
path:string;
delta?:number;
[propName: string]: any;
}
export interface navRoute extends h5NextRule, navtoRule {
}
// 开始切换窗口动画 app端可用
export interface startAnimationRule {
animationType?: startAnimationType; // 窗口关闭的动画效果
animationDuration?: number; // 窗口关闭动画的持续时间
}
// 关闭窗口时的动画 app端可用
export interface endAnimationRule {
animationType?: endAnimationType; // 窗口关闭的动画效果
animationDuration?: number; // 窗口关闭动画的持续时间
}
export interface hookObjectRule {
options:Array<any>;
hook:Function;
}
// 执行路由跳转失败或者 next(false) 时走的规则
export interface navErrorRule {
type: navRuleStatus;
msg: string;
to?:totalNextRoute;
from?:totalNextRoute;
nextTo?:any;
[propName:string]:any;
}
// uni原生api跳转时的规则
export interface uniNavApiRule {
url: string;
openType?:'appLaunch',
query?:objectAny;
path?:string;
delta?:number;
detail?:{[propName:string]:any};
animationType?:startAnimationType;
animationDuration?:number;
events?:{[propName:string]:any};
success?:Function;
fail?:Function;
complete?:Function;
animation?:{
animationType?:startAnimationType;
animationDuration?:number;
}
}
export interface originMixins extends uniNavApiRule{
BACKTYPE:''|backTypeRule
}
// uni-app 原始返回api 回调参数
export interface uniBackRule{
from:backTypeRule;
}
export interface uniBackApiRule{
delta?: number;
animationDuration?: number;
animationType?:endAnimationType;
}
export type routesMapKeysRule=
'finallyPathList'|
'finallyPathMap'|
'aliasPathMap'|
'pathMap'|
'nameMap'|
'vueRouteMap';
export interface routesMapRule{
[key:string]:any;
finallyPathList: Array<string>;
finallyPathMap:RoutesRule;
aliasPathMap: RoutesRule;
pathMap: RoutesRule;
nameMap:RoutesRule,
vueRouteMap:objectAny
}
export interface routeRule{
name:string|undefined;
meta:objectAny;
path:string;
query:objectAny;
params:objectAny;
fullPath:string;
NAVTYPE:NAVTYPE|'';
BACKTYPE?:backTypeRule|''; // v2.0.5 +
[propName: string]: any;
}
export interface RoutesRule {
path: string; // pages.json中的path 必须加上 '/' 开头
component?: object; // H5端可用
name?: string; // 命名路由
components?: object; // 命名视图组件H5端可用
redirect?: string | Function; // H5端可用
props?: boolean | object | Function; // H5端可用
aliasPath?: string; // h5端 设置一个别名路径来替换 uni-app的默认路径
alias?: string | Array<string>; // H5端可用
children?: Array<RoutesRule>; // 嵌套路由H5端可用
beforeEnter?:guardHookRule; // 路由元守卫
meta?: any; // 其他格外参数
[propName: string]: any;
}
export interface Router {
readonly lifeCycle: LifeCycleConfig;
readonly options: InstantiateConfig;
$lockStatus:boolean;
$route: object | null;
enterPath:string;
runId:number;
Vue:any;
appMain:{
NAVTYPE:reNavMethodRule|reNotNavMethodRule,
path:string
}|{};
proxyHookDeps: proxyDepsRule;
routesMap: routesMapRule|{};
mount: Array<{app: any; el: string}>;
install(Vue: any): void;
push(to: totalNextRoute|navRoute | string,from?:totalNextRoute): void; // 动态的导航到一个新 URL 保留浏览历史
replace(to: totalNextRoute|navRoute | string,from?:totalNextRoute): void; // 动态的导航到一个新 URL 关闭当前页面,跳转到的某个页面。
replaceAll(to: totalNextRoute|navRoute | string,from?:totalNextRoute): void; // 动态的导航到一个新 URL 关闭所有页面,打开到应用内的某个页面
pushTab(to: totalNextRoute|navRoute | string,from?:totalNextRoute): void; // 动态的导航到一个新 url 关闭所有页面打开到应用内的某个tab
back(level:number|undefined,origin?:uniBackRule|uniBackApiRule):void;
forceGuardEach(navType:NAVTYPE|undefined,forceNav:boolean):void; //强制触发当前守卫
beforeEach(userGuard:guardHookRule): void; // 添加全局前置路由守卫
afterEach(userGuard:(to: totalNextRoute, from: totalNextRoute)=>void): void; // 添加全局后置路由守卫
}
export type PromiseResolve=(value?: void | PromiseLike<void> | undefined) => void;
// @ts-ignore
declare module 'vue/types/vue' {
interface Vue {
$Router: Router;
$Route: routeRule;
}
}

77
node_modules/uni-simple-router/src/options/config.ts generated vendored Normal file
View File

@@ -0,0 +1,77 @@
import {startAnimationRule, hookListRule, RoutesRule, navtoRule, navErrorRule, Router, objectAny, NAVTYPE, totalNextRoute, navRoute} from './base';
export type debuggerConfig=boolean|debuggerArrayConfig;
export type platformRule='h5'|'app-plus'|'app-lets'|'mp-weixin'|'mp-baidu'|'mp-alipay'|'mp-toutiao'|'mp-qq'|'mp-360';
export interface H5Config {
paramsToQuery?: boolean; // h5端上通过params传参时规则是vue-router 刷新会丢失 开启此开关将变成?连接的方式
vueRouterDev?: boolean; // 完全使用采用vue-router的开发模式
vueNext?: boolean; // 在next管道函数中是否获取vueRouter next的原本参数
mode?: string;
base?: string;
linkActiveClass?: string;
linkExactActiveClass?: string;
scrollBehavior?: Function;
fallback?: boolean;
}
export interface AppConfig {
registerLoadingPage?:boolean; // 是否注册过渡加载页 +v2.0.6
loadingPageStyle?: () => object; // 当前等待页面的样式 必须返回一个json
loadingPageHook?: (view:any)=>void; // 刚刚打开页面处于等待状态,会触发此函数
launchedHook?:()=>void; // 首次启动app完成
animation?: startAnimationRule; // 页面切换动画
}
export interface appletConfig {
animationDuration?:number; // 页面切换时间,有助于路由锁精准解锁
}
type hookRule=(args:Array<any>, next:(args:Array<any>)=>void, router:Router)=>void;
export interface proxyHooksConfig{
onLaunch?:hookRule;
onShow?:hookRule;
onHide?:hookRule;
onError?:hookRule;
onInit?:hookRule;
onLoad?:hookRule;
onReady?:hookRule;
onUnload?:hookRule;
onResize?:hookRule;
destroyed?:hookRule;
created?:hookRule;
beforeCreate?:hookRule;
beforeMount?:hookRule;
mounted?:hookRule;
beforeDestroy?:hookRule;
}
export interface debuggerArrayConfig{
error?:boolean;
warn?:boolean;
log?:boolean;
}
export interface InstantiateConfig {
[key:string]:any;
keepUniOriginNav?:boolean; // 重写uni-app的跳转方法关闭后使用uni-app的原始方法跳转和插件api跳转等同
platform:platformRule; // 当前运行平台
h5?: H5Config;
APP?: AppConfig;
applet?:appletConfig;
beforeProxyHooks?:proxyHooksConfig;
debugger?: debuggerConfig; // 是否处于开发阶段 设置为true则打印日志
routerBeforeEach?: (to:navtoRule, from:navtoRule, next:(rule?: navtoRule|false)=>void) => void; // router 前置路由函数 每次触发跳转前先会触发此函数
routerAfterEach?: (to:navtoRule, from:navtoRule, next?: Function) => void; // router 后置路由函数 每次触发跳转后会触发此函数
routerErrorEach?: (error: navErrorRule, router:Router) => void;
resolveQuery?:(jsonQuery:objectAny)=>objectAny; // 跳转之前把参数传递给此函数、返回最终的数据!有此函数不走默认方法
parseQuery?:(jsonQuery:objectAny)=>objectAny; // 读取值之前把参数传递给此函数,返回最终的数据!有此函数不走默认方法
detectBeforeLock?:(router:Router, to:string|number|totalNextRoute|navRoute, navType:NAVTYPE)=>void; // 在检测路由锁之前触发的函数
routes: RoutesRule[];
}
export interface LifeCycleConfig{
beforeHooks: hookListRule;
afterHooks: hookListRule;
routerBeforeHooks: hookListRule;
routerAfterHooks: hookListRule;
routerErrorHooks: Array<(error:navErrorRule, router:Router)=>void>;
}

View File

@@ -0,0 +1,46 @@
import { voidFun } from '../helpers/utils';
import { warn } from '../helpers/warn';
import { Router, vueHookNameRule } from '../options/base';
export function beforeProxyHook(
Vim:any,
router:Router
):boolean {
const hookOptions = Vim.$options;
const {beforeProxyHooks} = router.options;
if (hookOptions == null) {
return false;
}
if (beforeProxyHooks == null) {
return false;
}
const keyArray = Object.keys(beforeProxyHooks) as Array<vueHookNameRule>;
for (let i = 0; i < keyArray.length; i++) {
const key = keyArray[i];
const hooksArray:Array<Function>|null = hookOptions[key];
if (hooksArray) {
const beforeProxyFun = beforeProxyHooks[key];
for (let j = 0; j < hooksArray.length; j++) {
const hookFun = hooksArray[j];
if (hookFun.toString().includes($npm_package_name)) {
continue
}
const [oldHook] = hooksArray.splice(j, 1, function myReplace(this: any, ...args:Array<any>) {
const pluginMarkId = $npm_package_name;
voidFun(pluginMarkId);
if (beforeProxyFun) {
beforeProxyFun.call(this, args, (options) => {
oldHook.apply(this, options)
}, router);
} else {
oldHook.apply(this, args)
}
});
}
} else {
warn(`beforeProxyHooks ===> 当前组件不适合${key},或者 hook: ${key} 不存在,已为你规避处理,可以忽略。`, router)
}
}
return true
}

181
node_modules/uni-simple-router/src/public/hooks.ts generated vendored Normal file
View File

@@ -0,0 +1,181 @@
import {
Router,
hookListRule,
navtoRule,
reloadNavRule,
totalNextRoute,
hookToggle,
NAVTYPE,
navErrorRule,
objectAny
} from '../options/base';
import {
routesForMapRoute,
getDataType,
forMatNextToFrom,
getUniCachePage,
voidFun
} from '../helpers/utils'
import { navjump } from './methods';
import { proxyH5Mount } from '../H5/proxyHook';
import { addKeepAliveInclude } from '../H5/patch';
import { tabIndexSelect } from '../app/appPatch';
export const ERRORHOOK:Array<(error:navErrorRule, router:Router)=>void> = [
(error, router) => router.lifeCycle.routerErrorHooks[0](error, router)
]
export const HOOKLIST: hookListRule = [
(router, to, from, toRoute, next) => callHook(router.lifeCycle.routerBeforeHooks[0], to, from, router, next),
(router, to, from, toRoute, next) => callBeforeRouteLeave(router, to, from, next),
(router, to, from, toRoute, next) => callHook(router.lifeCycle.beforeHooks[0], to, from, router, next),
(router, to, from, toRoute, next) => callHook(toRoute.beforeEnter, to, from, router, next),
(router, to, from, toRoute, next) => callHook(router.lifeCycle.afterHooks[0], to, from, router, next, false),
(router, to, from, toRoute, next) => {
router.$lockStatus = false;
if (router.options.platform === 'h5') {
proxyH5Mount(router);
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/316 2021年12月10日14:30:13
addKeepAliveInclude(router);
}
router.runId++;
return callHook(router.lifeCycle.routerAfterHooks[0], to, from, router, next, false)
}
];
export function callBeforeRouteLeave(
router:Router,
to:totalNextRoute,
from:totalNextRoute,
resolve:Function
):void {
const page = getUniCachePage<objectAny>(0);
let beforeRouteLeave;
if (Object.keys(page).length > 0) {
let leaveHooks:Array<Function>|undefined|Function;
if (router.options.platform === 'h5') {
leaveHooks = (page as objectAny).$options.beforeRouteLeave;
} else {
if ((page as objectAny).$vm != null) {
leaveHooks = (page as objectAny).$vm.$options.beforeRouteLeave;
}
}
switch (getDataType<Array<Function>>((leaveHooks as Array<Function>))) {
case '[object Array]': // h5端表现
beforeRouteLeave = (leaveHooks as Array<Function>)[0];
beforeRouteLeave = beforeRouteLeave.bind(page)
break;
case '[object Function]': // 目前app端表现
beforeRouteLeave = (leaveHooks as Function).bind((page as objectAny).$vm);
break
}
}
return callHook(beforeRouteLeave, to, from, router, resolve);
}
export function callHook(
hook:Function|undefined,
to:totalNextRoute,
from: totalNextRoute,
router:Router,
resolve:Function,
hookAwait:boolean|undefined = true
):void {
if (hook != null && hook instanceof Function) {
if (hookAwait === true) {
hook(to, from, resolve, router, false);
} else {
hook(to, from, () => {}, router, false);
resolve();
}
} else {
resolve();
}
}
export function onTriggerEachHook(
to:totalNextRoute,
from: totalNextRoute,
router:Router,
hookType:hookToggle,
next:(rule?: navtoRule|false)=>void,
):void {
let callHookList:hookListRule = [];
switch (hookType) {
case 'beforeEach':
callHookList = HOOKLIST.slice(0, 3);
break;
case 'afterEach':
callHookList = HOOKLIST.slice(4);
break
case 'beforeEnter':
callHookList = HOOKLIST.slice(3, 4);
break;
}
transitionTo(router, to, from, 'push', callHookList, next);
}
export function transitionTo(
router:Router,
to:totalNextRoute,
from: totalNextRoute,
navType:NAVTYPE,
callHookList:hookListRule,
hookCB:Function
) :void{
const {matTo, matFrom} = forMatNextToFrom<totalNextRoute>(router, to, from);
if (router.options.platform === 'h5') {
loopCallHook(callHookList, 0, hookCB, router, matTo, matFrom, navType);
} else {
loopCallHook(callHookList.slice(0, 4), 0, () => {
hookCB(() => { // 非H5端等他跳转完才触发最后两个生命周期
loopCallHook(callHookList.slice(4), 0, voidFun, router, matTo, matFrom, navType);
});
}, router, matTo, matFrom, navType);
}
}
export function loopCallHook(
hooks:hookListRule,
index:number,
next:Function,
router:Router,
matTo:totalNextRoute,
matFrom: totalNextRoute,
navType:NAVTYPE,
): void|Function {
const toRoute = routesForMapRoute(router, matTo.path, ['finallyPathMap', 'pathMap']);
if (hooks.length - 1 < index) {
return next();
}
const hook = hooks[index];
const errHook = ERRORHOOK[0];
hook(router, matTo, matFrom, toRoute, (nextTo:reloadNavRule) => {
if (router.options.platform === 'app-plus') {
if (nextTo === false || (typeof nextTo === 'string' || typeof nextTo === 'object')) {
tabIndexSelect(matTo, matFrom);
}
}
if (nextTo === false) {
if (router.options.platform === 'h5') {
next(false);
}
errHook({ type: 0, msg: '管道函数传递 false 导航被终止!', matTo, matFrom, nextTo }, router)
} else if (typeof nextTo === 'string' || typeof nextTo === 'object') {
let newNavType = navType;
let newNextTo = nextTo;
if (typeof nextTo === 'object') {
const {NAVTYPE: type, ...moreTo} = nextTo;
newNextTo = moreTo;
if (type != null) {
newNavType = type;
}
}
navjump(newNextTo, router, newNavType, {from: matFrom, next})
} else if (nextTo == null) {
index++;
loopCallHook(hooks, index, next, router, matTo, matFrom, navType)
} else {
errHook({ type: 1, msg: '管道函数传递未知类型,无法被识别。导航被终止!', matTo, matFrom, nextTo }, router)
}
});
}

263
node_modules/uni-simple-router/src/public/methods.ts generated vendored Normal file
View File

@@ -0,0 +1,263 @@
import {
NAVTYPE,
Router,
totalNextRoute,
objectAny,
routeRule,
reNavMethodRule,
rewriteMethodToggle,
navtypeToggle,
navErrorRule,
uniBackApiRule,
uniBackRule,
navRoute
} from '../options/base'
import {
queryPageToMap,
resolveQuery,
parseQuery
} from './query'
import {
voidFun,
paramsToQuery,
getUniCachePage,
routesForMapRoute,
copyData,
lockDetectWarn,
getDataType,
notRouteTo404,
deepDecodeQuery
} from '../helpers/utils'
import { transitionTo } from './hooks';
import {createFullPath, createToFrom} from '../public/page'
import {HOOKLIST} from './hooks'
export function lockNavjump(
to:string|totalNextRoute|navRoute,
router:Router,
navType:NAVTYPE,
forceNav?:boolean,
animation?:uniBackApiRule|uniBackRule
):void{
lockDetectWarn(router, to, navType, () => {
if (router.options.platform !== 'h5') {
router.$lockStatus = true;
}
navjump(to as totalNextRoute, router, navType, undefined, forceNav, animation);
}, animation);
}
export function navjump(
to:string|totalNextRoute,
router:Router,
navType:NAVTYPE,
nextCall?:{
from:totalNextRoute;
next:Function;
},
forceNav?:boolean,
animation?:uniBackApiRule|uniBackRule,
callHook:boolean|undefined = true
) :void|never|totalNextRoute {
if (navType === 'back') {
let level:number = 1;
if (typeof to === 'string') {
level = +to;
} else {
level = to.delta || 1;
// 主要剥离事件函数
animation = {
...animation || {},
...(to as uniBackApiRule)
}
}
if (router.options.platform === 'h5') {
(router.$route as any).go(-level);
// Fixe https://github.com/SilurianYang/uni-simple-router/issues/266 2021年6月3日11:14:38
// @ts-ignore
const success = (animation || {success: voidFun}).success || voidFun;
// @ts-ignore
const complete = (animation || {complete: voidFun}).complete || voidFun;
success({errMsg: 'navigateBack:ok'});
complete({errMsg: 'navigateBack:ok'});
return;
} else {
to = backOptionsBuild(router, level, animation);
}
}
const {rule} = queryPageToMap(to, router);
rule.type = navtypeToggle[navType];
const toRule = paramsToQuery(router, rule);
let parseToRule = resolveQuery(toRule as totalNextRoute, router);
if (router.options.platform === 'h5') {
if (navType !== 'push') {
navType = 'replace';
}
if (nextCall != null) { // next 管道函数拦截时 直接next即可
nextCall.next({
replace: navType !== 'push',
...parseToRule
})
} else {
// Fixe https://github.com/SilurianYang/uni-simple-router/issues/240 2021年3月7日14:45:36
if (navType === 'push' && Reflect.has(parseToRule, 'events')) {
if (Reflect.has(parseToRule, 'name')) {
throw new Error(`在h5端上使用 'push'、'navigateTo' 跳转时,如果包含 events 不允许使用 name 跳转,因为 name 实现了动态路由。请更换为 path 或者 url 跳转!`);
} else {
uni['navigateTo'](parseToRule, true, voidFun, forceNav);
}
} else {
(router.$route as any)[navType](parseToRule, (parseToRule as totalNextRoute).success || voidFun, (parseToRule as totalNextRoute).fail || voidFun)
}
}
} else {
let from:totalNextRoute = {path: ''};
if (nextCall == null) {
let toRoute = routesForMapRoute(router, parseToRule.path, ['finallyPathMap', 'pathMap']);
toRoute = notRouteTo404(router, toRoute, parseToRule, navType);
parseToRule = { ...toRoute, ...{params: {}}, ...parseToRule, ...{path: toRoute.path} }
from = createToFrom(parseToRule, router);
} else {
from = nextCall.from;
}
createFullPath(parseToRule, from);
if (callHook === false) {
return parseToRule;
}
transitionTo(router, parseToRule, from, navType, HOOKLIST, function(
callOkCb:Function
):void {
uni[navtypeToggle[navType]](parseToRule, true, callOkCb, forceNav);
})
}
}
export function backOptionsBuild(
router:Router,
level:number,
animation:uniBackApiRule|uniBackRule|undefined = {},
):totalNextRoute {
const toRule = createRoute(router, level, undefined, {NAVTYPE: 'back', ...animation});
const navjumpRule:totalNextRoute = {
...animation,
path: toRule.path,
query: toRule.query,
delta: level
}
if (getDataType<any>(animation) === '[object Object]') {
const {animationDuration, animationType} = (animation as uniBackApiRule)
if (animationDuration != null) {
navjumpRule.animationDuration = animationDuration;
}
if (animationType != null) {
navjumpRule.animationType = animationType;
}
const {from} = (animation as uniBackRule)
if (from != null) {
navjumpRule.BACKTYPE = from;
}
}
return navjumpRule;
}
export function forceGuardEach(
router:Router,
navType:NAVTYPE|undefined = 'replaceAll',
forceNav:undefined|boolean = false
):void|never {
if (router.options.platform === 'h5') {
throw new Error(`在h5端上使用forceGuardEach 是无意义的,目前 forceGuardEach 仅支持在非h5端上使用`);
}
const currentPage = getUniCachePage<objectAny>(0);
if (Object.keys(currentPage).length === 0) {
(router.options.routerErrorEach as (error: navErrorRule, router:Router) => void)({
type: 3,
NAVTYPE: navType,
uniActualData: {},
level: 0,
msg: `不存在的页面栈,请确保有足够的页面可用,当前 level:0`
}, router);
}
const {route, options} = currentPage as objectAny;
lockNavjump({
path: `/${route}`,
query: deepDecodeQuery(options || {})
}, router, navType, forceNav);
}
export function createRoute(
router:Router,
level:number|undefined = 0,
orignRule?:totalNextRoute,
uniActualData:objectAny|undefined = {},
):routeRule|never {
const route:routeRule = {
name: '',
meta: {},
path: '',
fullPath: '',
NAVTYPE: '',
query: {},
params: {},
BACKTYPE: (orignRule || {BACKTYPE: ''}).BACKTYPE || '' // v2.0.5 +
};
if (level === 19970806) { // 首次构建响应式 页面不存在 直接返回
return route
}
if (router.options.platform === 'h5') {
let vueRoute:totalNextRoute = {path: ''};
if (orignRule != null) {
vueRoute = orignRule;
} else {
vueRoute = (router.$route as objectAny).currentRoute;
}
const matRouteParams = copyData(vueRoute.params as objectAny);
delete matRouteParams.__id__;
const toQuery = parseQuery({...matRouteParams, ...copyData(vueRoute.query as objectAny)}, router);
vueRoute = {...vueRoute, query: toQuery}
route.path = vueRoute.path;
route.fullPath = vueRoute.fullPath || '';
route.query = deepDecodeQuery(vueRoute.query || {});
route.NAVTYPE = rewriteMethodToggle[vueRoute.type as reNavMethodRule || 'reLaunch'];
} else {
let appPage:objectAny = {};
if (orignRule != null) {
appPage = {...orignRule, openType: orignRule.type};
} else {
const page = getUniCachePage<objectAny>(level);
if (Object.keys(page).length === 0) {
const {NAVTYPE: _NAVTYPE, ..._args} = uniActualData;
const errorMsg:string = `不存在的页面栈,请确保有足够的页面可用,当前 level:${level}`;
(router.options.routerErrorEach as (error: navErrorRule, router:Router) => void)({
type: 3,
msg: errorMsg,
NAVTYPE: _NAVTYPE,
level,
uniActualData: _args
}, router);
throw new Error(errorMsg);
}
// Fixes: https://github.com/SilurianYang/uni-simple-router/issues/196
const pageOptions:objectAny = (page as objectAny).options || {};
appPage = {
...(page as objectAny).$page || {},
query: deepDecodeQuery(pageOptions),
fullPath: decodeURIComponent(((page as objectAny).$page || {}).fullPath || '/' + (page as objectAny).route)
}
if (router.options.platform !== 'app-plus') {
appPage.path = `/${(page as objectAny).route}`
}
}
const openType:reNavMethodRule|'navigateBack' = appPage.openType;
route.query = appPage.query;
route.path = appPage.path;
route.fullPath = appPage.fullPath;
route.NAVTYPE = rewriteMethodToggle[openType || 'reLaunch'];
}
const tableRoute = routesForMapRoute(router, route.path, ['finallyPathMap', 'pathMap'])
const perfectRoute = { ...route, ...tableRoute};
perfectRoute.query = parseQuery(perfectRoute.query, router);
return perfectRoute;
}

103
node_modules/uni-simple-router/src/public/page.ts generated vendored Normal file
View File

@@ -0,0 +1,103 @@
import { proxyHookName } from '../helpers/config';
import { getDataType, getUniCachePage, deepClone} from '../helpers/utils';
import { objectAny, pageTypeRule, Router, totalNextRoute, vueOptionRule } from '../options/base';
import {createRoute} from './methods'
import { stringifyQuery } from './query';
export function createToFrom(
to:totalNextRoute,
router:Router,
):totalNextRoute {
let fromRoute:totalNextRoute = {path: ''};
const page = getUniCachePage<Array<any>|objectAny>(0);
if (getDataType<Array<any>|objectAny>(page) === '[object Array]') {
fromRoute = deepClone<totalNextRoute>(to)
} else {
fromRoute = createRoute(router) as totalNextRoute;
}
return fromRoute;
}
export function createFullPath(
to:totalNextRoute,
from:totalNextRoute
):void{
if (to.fullPath == null) {
const strQuery = stringifyQuery(to.query as objectAny);
to.fullPath = to.path + strQuery;
}
if (from.fullPath == null) {
const strQuery = stringifyQuery(from.query as objectAny);
from.fullPath = from.path + strQuery;
}
}
export function proxyPageHook(
vueVim:any,
router:Router,
pageType:pageTypeRule
):void {
const hookDeps = router.proxyHookDeps;
const pageHook:vueOptionRule = vueVim.$options;
for (let i = 0; i < proxyHookName.length; i++) {
const hookName = proxyHookName[i];
const hookList = pageHook[hookName];
if (hookList) {
for (let k = 0; k < hookList.length; k++) {
const originHook = hookList[k];
if (originHook.toString().includes($npm_package_name)) {
continue
}
const resetIndex = Object.keys(hookDeps.hooks).length + 1
const proxyHook = (...args:Array<any>):void => {
hookDeps.resetIndex.push(resetIndex);
hookDeps.options[resetIndex] = args;
}
const [resetHook] = hookList.splice(k, 1, proxyHook);
hookDeps.hooks[resetIndex] = {
proxyHook,
callHook: (enterPath:string) :void => {
if (router.enterPath.replace(/^\//, '') !== enterPath.replace(/^\//, '') && pageType !== 'app') {
return;
}
const options = hookDeps.options[resetIndex];
resetHook.apply(vueVim, options);
},
resetHook: () :void => {
hookList.splice(k, 1, resetHook)
}
};
}
}
}
}
export function resetAndCallPageHook(
router:Router,
enterPath:string,
reset:boolean|undefined = true
):void{
// Fixe: https://github.com/SilurianYang/uni-simple-router/issues/206
const pathInfo = enterPath.trim().match(/^(\/?[^\?\s]+)(\?[\s\S]*$)?$/);
if (pathInfo == null) {
throw new Error(`还原hook失败。请检查 【${enterPath}】 路径是否正确。`);
}
enterPath = pathInfo[1];
const proxyHookDeps = router.proxyHookDeps;
const resetHooksArray = proxyHookDeps.resetIndex
for (let i = 0; i < resetHooksArray.length; i++) {
const index = resetHooksArray[i];
const {callHook} = proxyHookDeps.hooks[index];
callHook(enterPath);
}
if (reset) {
resetPageHook(router);
}
}
export function resetPageHook(
router:Router
) {
const proxyHookDeps = router.proxyHookDeps;
for (const [, {resetHook}] of Object.entries(proxyHookDeps.hooks)) {
resetHook();
}
}

200
node_modules/uni-simple-router/src/public/query.ts generated vendored Normal file
View File

@@ -0,0 +1,200 @@
import {
objectAny,
Router,
routesMapRule,
RoutesRule,
totalNextRoute
} from '../options/base';
import {
getDataType,
urlToJson,
routesForMapRoute,
getRoutePath,
assertDeepObject,
copyData,
getWildcardRule,
deepDecodeQuery
} from '../helpers/utils'
import {ERRORHOOK} from './hooks'
import {warn} from '../helpers/warn'
const encodeReserveRE = /[!'()*]/g
const encodeReserveReplacer = (c:string) => '%' + c.charCodeAt(0).toString(16)
const commaRE = /%2C/g
const encode = (str:string) =>
encodeURIComponent(str)
.replace(encodeReserveRE, encodeReserveReplacer)
.replace(commaRE, ',')
export function queryPageToMap(
toRule:string|totalNextRoute,
router:Router
) :{
rule:totalNextRoute;
route:RoutesRule,
query:objectAny
} {
let query:objectAny = {};
let route:RoutesRule|string = '';
let successCb = (toRule as totalNextRoute).success;
let failCb = (toRule as totalNextRoute).fail;
if (getDataType<string|totalNextRoute>(toRule) === '[object Object]') {
const objNavRule = (toRule as totalNextRoute);
if (objNavRule.path != null) {
const {path, query: newQuery} = urlToJson(objNavRule.path);
route = routesForMapRoute(router, path, ['finallyPathList', 'pathMap']);
query = {...newQuery, ...((toRule as totalNextRoute).query || {})};
objNavRule.path = path;
objNavRule.query = query;
delete (toRule as totalNextRoute).params;
} else if (objNavRule.name != null) {
route = (router.routesMap as routesMapRule).nameMap[objNavRule.name];
if (route == null) {
route = getWildcardRule(router, { type: 2, msg: `命名路由为:${objNavRule.name} 的路由,无法在路由表中找到!`, toRule});
} else {
query = (toRule as totalNextRoute).params || {};
delete (toRule as totalNextRoute).query;
}
} else {
route = getWildcardRule(router, { type: 2, msg: `${toRule} 解析失败,请检测当前路由表下是否有包含。`, toRule});
}
} else {
toRule = urlToJson((toRule as string)) as totalNextRoute;
route = routesForMapRoute(router, toRule.path, ['finallyPathList', 'pathMap'])
query = toRule.query as objectAny;
}
if (router.options.platform === 'h5') {
const {finallyPath} = getRoutePath(route as RoutesRule, router);
if (finallyPath.includes(':') && (toRule as totalNextRoute).name == null) {
ERRORHOOK[0]({ type: 2, msg: `当有设置 alias或者aliasPath 为动态路由时,不允许使用 path 跳转。请使用 name 跳转!`, route}, router)
}
const completeCb = (toRule as totalNextRoute).complete;
const cacheSuccess = (toRule as totalNextRoute).success;
const cacheFail = (toRule as totalNextRoute).fail;
if (getDataType<Function|undefined>(completeCb) === '[object Function]') {
const publicCb = function(this:any, args:Array<any>, callHook:Function|undefined):void {
if (getDataType<Function|undefined>(callHook) === '[object Function]') {
(callHook as Function).apply(this, args);
}
(completeCb as Function).apply(this, args);
}
successCb = function(this:any, ...args:any):void{
publicCb.call(this, args, cacheSuccess);
};
failCb = function(this:any, ...args:any):void{
publicCb.call(this, args, cacheFail);
};
}
}
const rule = (toRule as totalNextRoute);
if (getDataType<Function|undefined>(rule.success) === '[object Function]') {
rule.success = successCb;
}
if (getDataType<Function|undefined>(rule.fail) === '[object Function]') {
rule.fail = failCb;
}
return {
rule,
route: (route as RoutesRule),
query
}
}
export function resolveQuery(
toRule:totalNextRoute,
router:Router
):totalNextRoute {
let queryKey:'params'|'query' = 'query';
if (toRule.params as objectAny != null) {
queryKey = 'params';
}
if (toRule.query as objectAny != null) {
queryKey = 'query';
}
const query = copyData(toRule[queryKey] || {});
const {resolveQuery: userResolveQuery} = router.options;
if (userResolveQuery) {
const jsonQuery = userResolveQuery(query);
if (getDataType<objectAny>(jsonQuery) !== '[object Object]') {
warn('请按格式返回参数: resolveQuery?:(jsonQuery:{[propName: string]: any;})=>{[propName: string]: any;}', router)
} else {
toRule[queryKey] = jsonQuery;
}
} else {
const deepObj = assertDeepObject(query as objectAny);
if (!deepObj) {
return toRule;
}
const encode = JSON.stringify(query);
toRule[queryKey] = {
query: encode
}
}
return toRule
}
export function parseQuery(
query:objectAny,
router:Router,
):objectAny {
const {parseQuery: userParseQuery} = router.options;
if (userParseQuery) {
query = userParseQuery(copyData(query));
if (getDataType<objectAny>(query) !== '[object Object]') {
warn('请按格式返回参数: parseQuery?:(jsonQuery:{[propName: string]: any;})=>{[propName: string]: any;}', router)
}
} else {
if (Reflect.get(query, 'query')) { // 验证一下是不是深度对象
let deepQuery = Reflect.get(query, 'query');
if (typeof deepQuery === 'string') {
try {
deepQuery = JSON.parse(deepQuery);
} catch (error) {
warn('尝试解析深度对象失败,按原样输出。' + error, router)
}
}
if (typeof deepQuery === 'object') {
return deepDecodeQuery(deepQuery);
}
}
}
return query
}
export function stringifyQuery(obj:objectAny): string {
const res = obj
? Object.keys(obj)
.map(key => {
const val = obj[key]
if (val === undefined) {
return ''
}
if (val === null) {
return encode(key)
}
if (Array.isArray(val)) {
const result:Array<any> = []
val.forEach(val2 => {
if (val2 === undefined) {
return
}
if (val2 === null) {
result.push(encode(key))
} else {
result.push(encode(key) + '=' + encode(val2))
}
})
return result.join('&')
}
return encode(key) + '=' + encode(val)
})
.filter(x => x.length > 0)
.join('&')
: null
return res ? `?${res}` : ''
}

177
node_modules/uni-simple-router/src/public/rewrite.ts generated vendored Normal file
View File

@@ -0,0 +1,177 @@
import {
uniNavApiRule,
reNavMethodRule,
reNotNavMethodRule,
Router,
rewriteMethodToggle,
uniBackRule,
uniBackApiRule,
navtoRule,
totalNextRoute,
originMixins,
objectAny
} from '../options/base'
import {
routesForMapRoute,
getRoutePath,
getDataType,
notDeepClearNull,
resolveAbsolutePath,
getUniCachePage,
timeOut
} from '../helpers/utils'
import {
warn
} from '../helpers/warn'
import {uniOriginJump} from './uniOrigin'
import { HomeNvueSwitchTab } from '../app/appPatch';
const rewrite: Array<reNavMethodRule|reNotNavMethodRule> = [
'navigateTo',
'redirectTo',
'reLaunch',
'switchTab',
'navigateBack'
];
const cacheOldMethod:{
navigateTo:Function;
redirectTo:Function;
reLaunch:Function;
switchTab:Function;
navigateBack:Function;
} = {
navigateTo: () => {},
redirectTo: () => {},
reLaunch: () => {},
switchTab: () => {},
navigateBack: () => {}
}
export function rewriteMethod(
router:Router
): void {
if (router.options.keepUniOriginNav === false) {
rewrite.forEach(name => {
const oldMethod: Function = uni[name];
cacheOldMethod[name] = oldMethod;
uni[name] = async function(
params:originMixins|{from:string}|navtoRule,
originCall:boolean = false,
callOkCb?:Function,
forceNav?:boolean
):Promise<void> {
if (originCall) {
if (router.options.platform === 'app-plus') {
await HomeNvueSwitchTab(router, (params as navtoRule), cacheOldMethod['reLaunch']);
}
uniOriginJump(router, oldMethod, name, params as originMixins, callOkCb, forceNav)
} else {
if (router.options.platform === 'app-plus') {
if (Object.keys(router.appMain).length === 0) {
router.appMain = {
NAVTYPE: name,
path: (params as uniNavApiRule).url
}
}
}
callRouterMethod(params as uniNavApiRule, name, router);
}
};
})
}
}
function callRouterMethod(
option: uniNavApiRule|uniBackRule|uniBackApiRule,
funName:reNavMethodRule|reNotNavMethodRule,
router:Router
): void {
if (router.options.platform === 'app-plus') {
let openType = null;
if (option) {
openType = (option as uniNavApiRule).openType;
}
if (openType != null && openType === 'appLaunch') {
funName = 'reLaunch'
}
}
if (funName === 'reLaunch' && JSON.stringify(option) === '{"url":"/"}') {
warn(
`uni-app 原生方法reLaunch({url:'/'}) 默认被重写啦!你可以使用 this.$Router.replaceAll() 或者 uni.reLaunch({url:'/?xxx=xxx'})`,
router
);
funName = 'navigateBack';
option = {
from: 'backbutton'
}
}
if (funName === 'navigateBack') {
let level:number = 1;
if (option == null) {
option = {delta: 1};
}
if (getDataType<number|undefined>((option as uniBackApiRule).delta) === '[object Number]') {
level = ((option as uniBackApiRule).delta as number);
}
router.back(level, (option as uniBackRule|uniBackApiRule));
} else {
const routerMethodName = rewriteMethodToggle[(funName as reNavMethodRule)]
let path = (option as uniNavApiRule).url;
if (!path.startsWith('/')) {
const absolutePath = resolveAbsolutePath(path, router);
path = absolutePath;
(option as uniNavApiRule).url = absolutePath;
}
if (funName === 'switchTab') {
const route = routesForMapRoute(router, path, ['pathMap', 'finallyPathList'])
const {finallyPath} = getRoutePath(route, router);
if (getDataType<string | string[]>(finallyPath) === '[object Array]') {
warn(
`uni-app 原生方法跳转路径为:${path}。此路为是tab页面时不允许设置 alias 为数组的情况,并且不能为动态路由!当然你可以通过通配符*解决!`,
router
);
}
if ((finallyPath as string) === '*') {
warn(
`uni-app 原生方法跳转路径为:${path}。在路由表中找不到相关路由表!当然你可以通过通配符*解决!`,
router
);
}
// Fixe h5 端无法触发 onTabItemTap hook 2021年6月3日17:26:47
if (router.options.platform === 'h5') {
const {success: userSuccess} = option as uniNavApiRule;
(option as uniNavApiRule).success = (...args:Array<any>) => {
userSuccess?.apply(null, args);
timeOut(150).then(() => {
const cbArgs = (option as uniNavApiRule).detail || {};
if (Object.keys(cbArgs).length > 0 && Reflect.has(cbArgs, 'index')) {
const cachePage = getUniCachePage(0);
if (Object.keys(cachePage).length === 0) {
return false
}
const page = cachePage as objectAny;
const hooks = page.$options.onTabItemTap;
if (hooks) {
for (let j = 0; j < hooks.length; j++) {
hooks[j].call(page, cbArgs)
}
}
}
});
}
}
path = (finallyPath as string);
}
const {events, success, fail, complete, animationType, animationDuration} = option as uniNavApiRule;
const jumpOptions:totalNextRoute = {path, events, success, fail, complete, animationDuration, animationType};
router[routerMethodName](
notDeepClearNull<totalNextRoute>(jumpOptions)
)
}
}

136
node_modules/uni-simple-router/src/public/router.ts generated vendored Normal file
View File

@@ -0,0 +1,136 @@
import {PromiseResolve, Router, uniBackApiRule, uniBackRule} from '../options/base';
import {InstantiateConfig, LifeCycleConfig} from '../options/config';
import { lifeCycle, proxyHookDeps} from '../helpers/config';
import {assertNewOptions, def, getDataType} from '../helpers/utils';
import {registerRouterHooks, registerEachHooks} from '../helpers/lifeCycle';
import {initMixins} from '../helpers/mixins'
import {lockNavjump, forceGuardEach, createRoute} from '../public/methods'
import {rewriteMethod} from '../public/rewrite'
let AppReadyResolve:PromiseResolve = () => {};
const AppReady:Promise<void> = new Promise(resolve => (AppReadyResolve = resolve));
function createRouter(
params: InstantiateConfig
):Router {
const options = assertNewOptions<InstantiateConfig>(params);
const router:Router = {
options,
mount: [],
runId: 0,
Vue: null,
proxyHookDeps: proxyHookDeps,
appMain: {},
enterPath: '',
$route: null,
$lockStatus: false,
routesMap: {},
lifeCycle: registerRouterHooks<LifeCycleConfig>(lifeCycle, options),
push(to) {
lockNavjump(to, router, 'push');
},
replace(to) {
lockNavjump(to, router, 'replace');
},
replaceAll(to) {
lockNavjump(to, router, 'replaceAll');
},
pushTab(to) {
lockNavjump(to, router, 'pushTab');
},
back(level = 1, animation) {
if (getDataType(animation) !== '[object Object]') {
const backRule:uniBackRule = {
from: 'navigateBack'
}
animation = backRule;
} else {
if (!Reflect.has((animation as uniBackRule | uniBackApiRule), 'from')) {
animation = {
...animation,
from: 'navigateBack'
};
}
}
lockNavjump(level + '', router, 'back', undefined, animation)
},
forceGuardEach(navType, forceNav) {
forceGuardEach(router, navType, forceNav)
},
beforeEach(userGuard):void {
registerEachHooks(router, 'beforeHooks', userGuard);
},
afterEach(userGuard):void {
registerEachHooks(router, 'afterHooks', userGuard);
},
install(Vue:any):void{
router.Vue = Vue;
rewriteMethod(this);
initMixins(Vue, this);
Object.defineProperty(Vue.prototype, '$Router', {
get() {
const actualData = router;
Object.defineProperty(this, '$Router', {
value: actualData,
writable: false,
configurable: false,
enumerable: false
});
return Object.seal(actualData);
}
});
Object.defineProperty(Vue.prototype, '$Route', {
get() {
return createRoute(router);
}
});
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/254
Object.defineProperty(Vue.prototype, '$AppReady', {
get() {
if (router.options.platform === 'h5') {
return Promise.resolve();
}
return AppReady;
},
set(value:boolean) {
if (value === true) {
AppReadyResolve();
}
}
});
}
}
def(router, 'currentRoute', () => createRoute(router));
router.beforeEach((to, from, next) => next());
router.afterEach(() => {});
return router;
}
function RouterMount(
Vim:any,
router:Router,
el:string | undefined = '#app'
) :void|never {
if (getDataType<Array<any>>(router.mount) === '[object Array]') {
router.mount.push({
app: Vim,
el
})
} else {
throw new Error(`挂载路由失败router.app 应该为数组类型。当前类型:${typeof router.mount}`);
}
if (router.options.platform === 'h5') {
const vueRouter = (router.$route as any);
vueRouter.replace({
path: vueRouter.currentRoute.fullPath
});
} // 其他端目前不需要做啥
}
export {
RouterMount,
createRouter
}

112
node_modules/uni-simple-router/src/public/uniOrigin.ts generated vendored Normal file
View File

@@ -0,0 +1,112 @@
import { originMixins, reNavMethodRule, reNotNavMethodRule, Router, startAnimationRule, uniNavApiRule } from '../options/base';
import { stringifyQuery } from './query';
import {notDeepClearNull, timeOut} from '../helpers/utils'
import { mpPlatformReg } from '../helpers/config';
import { resetAndCallPageHook, resetPageHook } from './page';
let routerNavCount:number = 0;
let lastNavType:reNavMethodRule|reNotNavMethodRule = 'reLaunch'
export function uniOriginJump(
router:Router,
originMethod:Function,
funName:reNavMethodRule|reNotNavMethodRule,
options: originMixins,
callOkCb?:Function,
forceNav?:boolean
):void {
const {complete, ...originRule} = formatOriginURLQuery(router, options, funName);
const platform = router.options.platform;
if (forceNav != null && forceNav === false) {
if (routerNavCount === 0) {
routerNavCount++
if (platform !== 'h5') {
resetAndCallPageHook(router, originRule.url) // 还原及执行app.vue及首页下已经重写后的生命周期
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/254
// 在小程序端 next 直接放行会执行这个
router.Vue.prototype.$AppReady = true;
}
}
complete && complete.apply(null, {msg: 'forceGuardEach强制触发并且不执行跳转'});
callOkCb && callOkCb.apply(null, {msg: 'forceGuardEach强制触发并且不执行跳转'})
} else {
if (routerNavCount === 0) {
if (platform === 'app-plus') {
resetAndCallPageHook(router, originRule.url) // 还原及执行app.vue下已经重写后的生命周期
} else {
if (new RegExp(mpPlatformReg, 'g').test(platform)) {
// 其他就是在小程序下,首次启动发生跳转会走这里
// 我们先将app.vue的生命周期执行
resetAndCallPageHook(router, originRule.url, false)
}
}
}
originMethod({
...originRule,
from: options.BACKTYPE,
complete: async function(...args:Array<any>) {
if (routerNavCount === 0) {
routerNavCount++
if (platform !== 'h5') {
if (new RegExp(mpPlatformReg, 'g').test(platform)) { // 跳转完成后小程序下还原生命周期
resetPageHook(router);
}
// 【Fixe】 https://github.com/SilurianYang/uni-simple-router/issues/254
// 在小程序端 第一次 next 做跳转 会触发这个 、在app端首次必定会触发这个
router.Vue.prototype.$AppReady = true;
if (platform === 'app-plus') {
const waitPage = plus.nativeObj.View.getViewById('router-loadding');
waitPage && waitPage.close();
const launchedHook = router.options.APP?.launchedHook;
launchedHook && launchedHook();
}
}
}
let time:number = 0;
if (new RegExp(mpPlatformReg, 'g').test(platform)) {
time = (router.options.applet?.animationDuration) as number
} else if (platform === 'app-plus') {
if (funName === 'navigateBack' && lastNavType === 'navigateTo') {
time = (router.options.APP?.animation?.animationDuration) as number
}
}
if (funName === 'navigateTo' || funName === 'navigateBack') {
if (time !== 0) {
await timeOut(time);
}
}
lastNavType = funName;
complete && complete.apply(null, args);
callOkCb && callOkCb.apply(null, args)
}
});
}
}
export function formatOriginURLQuery(
router:Router,
options:uniNavApiRule,
funName:reNavMethodRule|reNotNavMethodRule
):uniNavApiRule {
const {url, path, query, animationType, animationDuration, events, success, fail, complete, delta, animation} = options;
const strQuery = stringifyQuery(query || {});
const queryURL = strQuery === '' ? (path || url) : (path || url) + strQuery;
let animationRule:startAnimationRule = {};
if (router.options.platform === 'app-plus') {
if (funName !== 'navigateBack') {
animationRule = router.options.APP?.animation || {};
animationRule = {...animationRule, ...animation || {}};
}
}
return notDeepClearNull<uniNavApiRule>({
delta,
url: queryURL,
animationType: animationType || animationRule.animationType,
animationDuration: animationDuration || animationRule.animationDuration,
events,
success,
fail,
complete
})
}