CNCEC_APP/uni_modules/uview-pro/libs/function/route.ts

119 lines
4.5 KiB
TypeScript
Raw Normal View History

2026-03-25 14:54:15 +08:00
/**
* 使uni.xxx的好处是使用更加简单快捷
*
*/
interface RouterConfig {
type?: string;
url?: string;
delta?: number;
params?: Record<string, any>;
animationType?: string;
animationDuration?: number;
intercept?: boolean;
}
declare const uni: any; // 声明uni对象避免ts报错
class Router {
config: RouterConfig;
// route: (options?: string | RouterConfig, params?: Record<string, any>) => Promise<void>;
constructor() {
// 原始属性定义
this.config = {
type: 'navigateTo',
url: '',
delta: 1, // navigateBack页面后退时,回退的层数
params: {}, // 传递的参数
animationType: 'pop-in', // 窗口动画,只在APP有效
animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效
intercept: false // 是否需要拦截
};
// 因为route方法是需要对外赋值给另外的对象使用同时route内部有使用this会导致route失去上下文
// 这里在构造函数中进行this绑定
this.route = this.route.bind(this);
}
// 判断url前面是否有"/",如果没有则加上,否则无法跳转
addRootPath(url: string): string {
return url[0] === '/' ? url : `/${url}`;
}
// 整合路由参数
mixinParam(url: string, params: Record<string, any>): string {
url = url && this.addRootPath(url);
// 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary"
// 如果有url中有get参数转换后无需带上"?"
let query = '';
if (/.*\/.*\?.*=.*/.test(url)) {
// object对象转为get类型的参数
query = uni.$u.queryParams(params, false);
// 因为已有get参数,所以后面拼接的参数需要带上"&"隔开
return url + '&' + query;
} else {
// 直接拼接参数因为此处url中没有后面的query参数也就没有"?/&"之类的符号
query = uni.$u.queryParams(params);
return url + query;
}
}
/**
*
* @param options url字符串
* @param params
*/
async route(options: string | RouterConfig = {}, params: Record<string, any> = {}): Promise<void> {
let mergeConfig: RouterConfig = {};
if (typeof options === 'string') {
// 如果options为字符串则为route(url, params)的形式
mergeConfig.url = this.mixinParam(options, params);
mergeConfig.type = 'navigateTo';
} else {
mergeConfig = uni.$u.deepMerge(this.config, options);
// 否则正常使用mergeConfig中的url和params进行拼接
mergeConfig.url = this.mixinParam(options.url || '', options.params || {});
}
if (params.intercept) {
this.config.intercept = params.intercept;
}
// params参数也带给拦截器
mergeConfig.params = params;
// 合并内外部参数
mergeConfig = uni.$u.deepMerge(this.config, mergeConfig);
// 判断用户是否定义了拦截器
if (uni.$u.routeIntercept && typeof uni.$u.routeIntercept === 'function') {
// 定一个promise根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转
const isNext = await new Promise<boolean>(resolve => {
uni.$u.routeIntercept(mergeConfig, resolve);
});
// 如果isNext为true则执行路由跳转
isNext && this.openPage(mergeConfig);
} else {
this.openPage(mergeConfig);
}
}
// 执行路由跳转
openPage(config: RouterConfig): void {
const { url = '', type = '', delta = 1, animationDuration = 300 } = config;
if (type == 'navigateTo' || type == 'to') {
uni.navigateTo({ url, animationDuration });
}
if (type == 'redirectTo' || type == 'redirect') {
uni.redirectTo({ url });
}
if (type == 'switchTab' || type == 'tab') {
uni.switchTab({ url });
}
if (type == 'reLaunch' || type == 'launch') {
uni.reLaunch({ url });
}
if (type == 'navigateBack' || type == 'back') {
uni.navigateBack({ delta });
}
}
}
export default new Router().route;