326 lines
5.4 KiB
TypeScript
326 lines
5.4 KiB
TypeScript
import { last } from "lodash-es";
|
|
import { ctx } from "virtual:ctx";
|
|
import { storage } from "../utils";
|
|
import { config } from "../../config";
|
|
|
|
type PushOptions =
|
|
| string
|
|
| {
|
|
path: string;
|
|
mode?: "navigateTo" | "redirectTo" | "reLaunch" | "switchTab" | "preloadPage";
|
|
events?: {
|
|
[key: string]: (data: any) => void;
|
|
};
|
|
query?: {
|
|
[key: string]: any;
|
|
};
|
|
params?: {
|
|
[key: string]: any;
|
|
};
|
|
isGuard?: boolean;
|
|
[key: string]: any;
|
|
};
|
|
|
|
type Tabs = {
|
|
text?: string;
|
|
pagePath: string;
|
|
iconPath?: string;
|
|
selectedIconPath?: string;
|
|
[key: string]: any;
|
|
}[];
|
|
|
|
// 路由列表
|
|
const routes = [...ctx.pages];
|
|
|
|
// 子包
|
|
if (ctx.subPackages) {
|
|
ctx.subPackages.forEach((a: { pages: any[]; root: string }) => {
|
|
a.pages.forEach((b) => {
|
|
routes.push({
|
|
...b,
|
|
path: a.root + "/" + b.path,
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// 钩子函数
|
|
const fn: { [key: string]: (...args: any[]) => any } = {};
|
|
|
|
// 路由
|
|
const router = {
|
|
// 底部导航
|
|
get tabs(): Tabs {
|
|
if (ctx.tabBar) {
|
|
return ctx.tabBar.list || [];
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
// 全局样式配置
|
|
globalStyle: ctx.globalStyle,
|
|
|
|
// 路由列表
|
|
routes,
|
|
|
|
// 地址栏参数
|
|
get query() {
|
|
const info = this.info();
|
|
|
|
return {
|
|
...info?.query,
|
|
};
|
|
},
|
|
|
|
// 临时参数
|
|
get params() {
|
|
return storage.get("router-params") || {};
|
|
},
|
|
|
|
// 页面地址
|
|
get pages() {
|
|
return {
|
|
home: "/" + (ctx.tabBar ? this.tabs[0].pagePath : ctx.pages[0].path),
|
|
...config.app.pages,
|
|
};
|
|
},
|
|
|
|
// 当前页
|
|
currentPage(): { [key: string]: any } {
|
|
return last(getCurrentPages())!;
|
|
},
|
|
|
|
// 当前页
|
|
get path() {
|
|
return router.info()?.path;
|
|
},
|
|
|
|
// 当前路由信息
|
|
info() {
|
|
const page = last(getCurrentPages());
|
|
|
|
if (page) {
|
|
const { route, $page, $vm, $getAppWebview }: any = page;
|
|
|
|
const q: any = {};
|
|
|
|
try {
|
|
$page?.fullPath
|
|
.split("?")[1]
|
|
.split("&")
|
|
.forEach((e: string) => {
|
|
const [k, v] = e.split("=");
|
|
q[k] = decodeURIComponent(v);
|
|
});
|
|
} catch (e) {}
|
|
|
|
// 页面配置
|
|
const style = this.routes.find((e) => e.path == route)?.style;
|
|
|
|
let d = {
|
|
$vm,
|
|
$getAppWebview,
|
|
path: `/${route}`,
|
|
fullPath: $page?.fullPath,
|
|
query: q || {},
|
|
isTab: this.isTab(route),
|
|
style,
|
|
isCustomNavbar: style?.navigationStyle == "custom",
|
|
};
|
|
|
|
return d;
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
|
|
// 跳转
|
|
push(options: PushOptions) {
|
|
if (typeof options == "string") {
|
|
options = {
|
|
path: options,
|
|
mode: "navigateTo",
|
|
};
|
|
}
|
|
|
|
let {
|
|
path,
|
|
mode = "navigateTo",
|
|
animationType,
|
|
animationDuration,
|
|
events,
|
|
success,
|
|
fail,
|
|
complete,
|
|
query,
|
|
params,
|
|
isGuard = true,
|
|
} = options || {};
|
|
|
|
if (query) {
|
|
let arr = [];
|
|
|
|
for (let i in query) {
|
|
if (query[i] !== undefined) {
|
|
arr.push(`${i}=${query[i]}`);
|
|
}
|
|
}
|
|
|
|
path += "?" + arr.join("&");
|
|
}
|
|
|
|
if (params) {
|
|
storage.set("router-params", params);
|
|
}
|
|
|
|
let data = {
|
|
url: path,
|
|
animationType,
|
|
animationDuration,
|
|
events,
|
|
success,
|
|
fail,
|
|
complete,
|
|
};
|
|
|
|
if (this.isTab(path)) {
|
|
mode = "switchTab";
|
|
}
|
|
|
|
const next = () => {
|
|
switch (mode) {
|
|
case "navigateTo":
|
|
uni.navigateTo(data);
|
|
break;
|
|
|
|
case "redirectTo":
|
|
uni.redirectTo(data);
|
|
break;
|
|
|
|
case "reLaunch":
|
|
uni.reLaunch(data);
|
|
break;
|
|
|
|
case "switchTab":
|
|
uni.switchTab(data);
|
|
break;
|
|
|
|
case "preloadPage":
|
|
uni.preloadPage(data);
|
|
break;
|
|
}
|
|
};
|
|
|
|
if (fn.beforeEach && isGuard) {
|
|
fn.beforeEach({ path: options.path, query }, next, (options: PushOptions) => {
|
|
this.push(options);
|
|
});
|
|
} else {
|
|
next();
|
|
}
|
|
},
|
|
|
|
// 后退
|
|
back(options?: UniApp.NavigateBackOptions) {
|
|
if (this.isFirstPage()) {
|
|
this.home();
|
|
} else {
|
|
uni.navigateBack(options || {});
|
|
}
|
|
},
|
|
|
|
// 执行当前页面的某个方法
|
|
callMethod(name: string, data?: any) {
|
|
const { $vm } = this.info()!;
|
|
|
|
if ($vm) {
|
|
if ($vm.$.exposed?.[name]) {
|
|
return $vm.$.exposed[name](data);
|
|
}
|
|
}
|
|
},
|
|
|
|
// 页面栈长度是否只有1
|
|
isFirstPage() {
|
|
return getCurrentPages().length == 1;
|
|
},
|
|
|
|
// 是否当前页
|
|
isCurrentPage(path: string) {
|
|
return this.info()?.path == path;
|
|
},
|
|
|
|
// 回到首页
|
|
home() {
|
|
this.push(this.pages.home);
|
|
},
|
|
|
|
// tabbar
|
|
switchTab(name: string) {
|
|
let item = this.tabs.find((e) => e.pagePath.includes(name));
|
|
|
|
if (item) {
|
|
this.push({
|
|
path: `/${item.pagePath}`,
|
|
mode: "switchTab",
|
|
});
|
|
} else {
|
|
console.error("不存在Tab页", name);
|
|
}
|
|
},
|
|
|
|
// 是否是Tab页
|
|
isTab(path: string) {
|
|
return !!this.tabs.find((e) => path == `/${e.pagePath}`);
|
|
},
|
|
|
|
// 去登陆
|
|
login(options?: { reLaunch: boolean }) {
|
|
const { reLaunch = false } = options || {};
|
|
|
|
this.push({
|
|
path: this.pages.login,
|
|
mode: reLaunch ? "reLaunch" : "navigateTo",
|
|
isGuard: false,
|
|
});
|
|
},
|
|
|
|
// 登录成功后操作
|
|
nextLogin(type?: string) {
|
|
const pages = getCurrentPages();
|
|
const index = pages.findIndex((e) => this.pages.login.includes(e.route!));
|
|
|
|
if (index <= 0) {
|
|
this.home();
|
|
} else {
|
|
router.back({
|
|
delta: pages.length - index,
|
|
});
|
|
}
|
|
|
|
// 登录方式
|
|
storage.set("loginType", type);
|
|
|
|
// 登录回调
|
|
if (fn.afterLogin) {
|
|
fn.afterLogin();
|
|
}
|
|
|
|
// 事件
|
|
uni.$emit("afterLogin", { type });
|
|
},
|
|
|
|
// 跳转前钩子
|
|
beforeEach(callback: (to: any, next: () => void) => void) {
|
|
fn.beforeEach = callback;
|
|
},
|
|
|
|
// 登录后回调
|
|
afterLogin(callback: () => void) {
|
|
fn.afterLogin = callback;
|
|
},
|
|
};
|
|
|
|
export { router };
|