小程序中的页面跳转分为 switchTab, navigateTo, redirectTo 三个方法。每次写跳转的时候都要考虑是怎样的跳转,该使用哪个方法,这无疑是不必要的心智负担。
为了解决这个问题就编写了一个统一跳转函数,整合了3个跳转方法。
话不多说,直接看代码:
import { navigateTo, redirectTo, switchTab } from '@tarojs/taro';
import { stringifyUrl } from 'query-string';
// app.config.ts 文件中编写了 tabBar,以及主包、分包的所有路由地址
import appConfig from '../app.config';
export type Callback = (res: TaroGeneral.CallbackResult) => void;
// 接收参数定义
export type Param = {
url: string; // 跳转地址
params?: {
// url 参数
[name: string]: string | number;
};
close?: boolean; // 是否关闭当前页。默认为 false
encode?: boolean; // url 参数是否 encodeURIComponent。默认为 false
// 下面的就是3个跳转方法可以接收的
complete?: Callback;
fail?: Callback;
success?: Callback;
events?: Record<string, any>;
};
// 通过 appConfig.tabBar 就能获取到所有 tabBar 的路由地址
const tabBarUrlList: string[] = appConfig.tabBar?.list?.map((item) => '/' + item.pagePath) || [];
/**
* 整合 navigateTo, redirectTo, switchTab
* url 可以不传 /pages 和最前面的 /,会自动补全
* 如:
* /tabBar/tab2/index -> /pages/tabBar/tab2/index
* tabBar/tab2/index -> /pages/tabBar/tab2/index
* /personalCenter/pages/vip/index -> /pages/personalCenter/pages/vip/index
* personalCenter/vip/index -> /pages/personalCenter/pages/vip/index
* @param {Param} param 接收的参数
* @example
* - 跳转 tabBar。params, close 参数不支持
* routTo({ url: 'tabBar/tab2/index' });
* - 跳转普通页面,关闭当前页,即 redirectTo,params 会作为 url 参数携带
* routeTo({ url: 'personalCenter/vip/index', params: { id: 'xxx' } });
* - 跳转普通页面,不关闭当前页,即 navigateTo,params 会作为 url 参数携带
* routTo({ url: 'personalCenter/vip/index', close: false, params: { id: 'xxxx' } });
*/
export default function routeTo(param: Param): Promise<TaroGeneral.CallbackResult> | void {
let { url, params, close = false, encode = false, complete, fail, success, events } = param;
if (!url) {
console.error('url 为空,跳转失败');
return;
}
url = url[0] === '/' ? url : '/' + url;
// url 可以不以 /pages 开头,帮忙补全 /pages
if (!url.startsWith('/pages')) {
url = '/pages' + url;
}
if (tabBarUrlList.includes(url)) {
// switchTab
if (process.env.NODE_ENV === 'development') {
if (params) {
console.error('跳转 tabBar,params 参数无效');
}
if (!close) {
console.error('跳转 tabBar,close 参数无效');
}
}
return switchTab({
url,
complete,
fail,
success
});
} else if (close) {
// redirectTo
url = stringifyUrl({ url, query: params }, { encode });
console.log('url============', url);
return redirectTo({
url,
complete,
fail,
success
});
} else {
// navigateTo
url = stringifyUrl({ url, query: params }, { encode });
console.log('url============', url);
return navigateTo({
url,
complete,
fail,
success,
events
});
}
}
主要思想就是可以通过 app.config.ts 拿到路由配置,从而判断跳转的页面类型,选择相应的跳转方法。
封装次函数的优点有:
- 不用关心跳转页面类型,减少心智负担。
- 由于项目架构设计主包分包都在 pages 目录下,所以可以在跳转的 url 中不传 pages,减少字符输入。
- url 中最前面的 / 可写可不写,会自动补全,比如从开发者工具中复制的页面路径就没有前面的 /,也能直接使用。
- 使用参数 close 控制跳转类型,更容易理解。使用参数 params 添加 url 参数,而不用字符串拼接,更合理。
后面项目中添加了启动页,就更体现出封装这个函数的意义了。用户可以从任意页面分享给好友,但是分享后的页面都是启动页加真实分享页面地址参数,没有这个函数就还是得判断分享的页面是不是 tabBar 从而选择对应的跳转方法,因为已经封装了这个函数,就直接使用进行跳转即可。