diff --git a/cool/ctx/index.ts b/cool/ctx/index.ts
index d5b57c9..07dd61e 100644
--- a/cool/ctx/index.ts
+++ b/cool/ctx/index.ts
@@ -64,7 +64,7 @@ if (isArray(ctx.subPackages)) {
PAGES.push({
path: a.root + "/" + b.path, // 拼接子包根路径和页面路径
style: b.style,
- meta: b.meta ?? {},
+ meta: b.meta
});
});
});
diff --git a/cool/router/index.ts b/cool/router/index.ts
index b398e17..5105c82 100644
--- a/cool/router/index.ts
+++ b/cool/router/index.ts
@@ -1,11 +1,24 @@
import { PAGES, TABS } from "../ctx";
import type { BackOptions, PageInstance, PushOptions } from "../types";
-import { storage, last, isNull, isEmpty, get, isFunction, toArray, map, debounce } from "../utils";
+import {
+ storage,
+ last,
+ isNull,
+ isEmpty,
+ get,
+ isFunction,
+ toArray,
+ map,
+ debounce,
+ nth
+} from "../utils";
// 路由信息类型
type RouteInfo = {
path: string;
- meta?: UTSJSONObject;
+ query: UTSJSONObject;
+ meta: UTSJSONObject;
+ isAuth?: boolean;
};
// 跳转前钩子类型
@@ -21,15 +34,11 @@ type Events = {
// 路由核心类
export class Router {
- private _events = {} as Events; // 事件存储
+ private eventsMap = {} as Events; // 事件存储
// 获取缓存的路由参数
params() {
- const data = storage.get("router-params") as UTSJSONObject;
- if (isNull(data)) {
- return {} as UTSJSONObject;
- }
- return data;
+ return (storage.get("router-params") ?? {}) as UTSJSONObject;
}
// 获取默认路径,支持 home 和 login
@@ -38,6 +47,7 @@ export class Router {
home: PAGES[0].path, // 首页为第一个页面
login: "/pages/user/login"
};
+
return get(paths, name) as string;
}
@@ -45,31 +55,38 @@ export class Router {
getPages(): PageInstance[] {
return map(getCurrentPages(), (e) => {
let path = e.route!;
+
// 根路径自动转为首页
if (path == "/") {
path = this.defaultPath("home");
}
+
// 补全路径前缀
if (!path.startsWith("/")) {
path = "/" + path;
}
+
// 获取页面样式
const page = PAGES.find((e) => e.path == path);
const style = page?.style;
const meta = page?.meta;
+
// 获取页面暴露的方法
// @ts-ignore
- let exposed = e.vm as any;
+ const vm = e.vm as any;
+
+ let exposed = vm;
+
// #ifdef H5
exposed = get(e, "vm.$.exposed");
// #endif
+
// 获取页面 query 参数
const query = (get(e, "options") ?? {}) as UTSJSONObject;
+
return {
path,
- // @ts-ignore
- vm: e.vm!,
- // @ts-ignore
+ vm,
exposed,
style,
meta,
@@ -113,7 +130,8 @@ export class Router {
complete,
animationType,
animationDuration,
- events
+ events,
+ isAuth
} = options;
// 拼接 query 参数到 url
@@ -176,15 +194,15 @@ export class Router {
};
// 跳转前钩子处理
- if (isFunction(this._events["beforeEach"])) {
- const meta = PAGES.find((e) => e.path == path)?.meta;
- const from = this.getPages().slice(-1)[0];
- const to: RouteInfo = { path, meta: meta ?? {} };
- (this._events["beforeEach"] as BeforeEach)(
- to,
- from,
- next
- );
+ if (this.eventsMap.beforeEach != null) {
+ // 当前页
+ const from = last(this.getPages());
+
+ // 跳转页
+ const to = { path, meta: this.getMeta(path), query, isAuth } as RouteInfo;
+
+ // 调用跳转前钩子
+ this.eventsMap.beforeEach(to, from!, next);
} else {
next();
}
@@ -197,31 +215,49 @@ export class Router {
});
}
- // 返回上一页,若为首页则回首页
+ // 返回上一页
back(options: BackOptions | null = null) {
- let path = ''
- const next = ()=>{
- if (this.isFirstPage()) {
- this.home();
- path = this.defaultPath("home")
- } else {
- path = this.getPages().slice(-2)[0].path;
+ if (this.isFirstPage()) {
+ this.home();
+ } else {
+ const delta = options?.delta ?? 1;
+
+ // 执行跳转函数
+ const next = () => {
uni.navigateBack({ ...(options ?? {}) });
+ };
+
+ // 跳转前钩子处理
+ if (this.eventsMap.beforeEach != null) {
+ // 当前页
+ const from = last(this.getPages());
+
+ // 上一页
+ const to = nth(this.getPages(), -delta - 1);
+
+ if (to != null) {
+ // 调用跳转前钩子
+ this.eventsMap.beforeEach(
+ {
+ path: to.path,
+ query: to.query,
+ meta: to.meta ?? ({} as UTSJSONObject)
+ },
+ from!,
+ next
+ );
+ } else {
+ console.error("[router] found to page is null");
+ }
+ } else {
+ next();
}
}
- // 跳转前钩子处理
- if (isFunction(this._events["beforeEach"])) {
- const meta = PAGES.find((e) => e.path == path)?.meta;
- const from = this.getPages().slice(-1)[0];
- const to: RouteInfo = { path, meta: meta ?? {} };
- (this._events["beforeEach"] as BeforeEach)(
- to,
- from,
- next
- );
- } else {
- next();
- }
+ }
+
+ // 获取页面元数据
+ getMeta(path: string) {
+ return PAGES.find((e) => e.path.includes(path))?.meta ?? ({} as UTSJSONObject);
}
// 执行当前页面暴露的方法
@@ -296,21 +332,21 @@ export class Router {
});
}
// 登录后回调
- if (isFunction(this._events["afterLogin"])) {
- (this._events["afterLogin"] as AfterLogin)();
+ if (this.eventsMap.afterLogin != null) {
+ this.eventsMap.afterLogin!();
}
// 触发全局 afterLogin 事件
uni.$emit("afterLogin");
}
// 注册跳转前钩子
- beforeEach(callback: BeforeEach) {
- this._events["beforeEach"] = callback;
+ beforeEach(cb: BeforeEach) {
+ this.eventsMap.beforeEach = cb;
}
// 注册登录后回调
- afterLogin(callback: AfterLogin) {
- this._events["afterLogin"] = callback;
+ afterLogin(cb: AfterLogin) {
+ this.eventsMap.afterLogin = cb;
}
}
diff --git a/cool/types/index.ts b/cool/types/index.ts
index 99ee80d..1146799 100644
--- a/cool/types/index.ts
+++ b/cool/types/index.ts
@@ -37,8 +37,9 @@ export type PushOptions = {
path: string;
mode?: PushMode;
events?: any;
- query?: any;
- params?: any;
+ query?: UTSJSONObject;
+ isAuth?: boolean;
+ params?: UTSJSONObject;
animationType?: PushAnimationType;
animationDuration?: number;
success?: (result: any) => void;
diff --git a/manifest.json b/manifest.json
index beaa1aa..6a19bed 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,13 +1,11 @@
{
"name": "cool-unix",
- "appid": "__UNI__EC807C1",
+ "appid": "__UNI__651711F",
"description": "完全开源、永久免费、上手容易、效率极高的开发脚手架",
"versionName": "1.0.0",
"versionCode": "100",
"uni-app-x": {},
- /* 快应用特有相关 */
"quickapp": {},
- /* 小程序特有相关 */
"mp-weixin": {
"darkmode": true,
"appid": "wxdebc4de0b5584ca4",
@@ -93,4 +91,4 @@
"splashScreens": {}
}
}
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index f880e09..bc17082 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cool-unix",
- "version": "8.0.25",
+ "version": "8.0.26",
"license": "MIT",
"scripts": {
"build-ui": "node ./uni_modules/cool-ui/scripts/generate-types.js",
diff --git a/pages.json b/pages.json
index 294c696..966d3c3 100644
--- a/pages.json
+++ b/pages.json
@@ -28,7 +28,7 @@
"style": {
"navigationBarTitleText": "设置"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -37,7 +37,7 @@
"style": {
"navigationBarTitleText": "通用设置"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -46,7 +46,7 @@
"style": {
"navigationBarTitleText": "通知设置"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -55,7 +55,7 @@
"style": {
"navigationBarTitleText": ""
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -64,7 +64,7 @@
"style": {
"navigationBarTitleText": "联系客服"
},
- "meta":{
+ "meta": {
"isAuth": true
}
}
@@ -78,7 +78,7 @@
"style": {
"navigationBarTitleText": "编辑资料"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -87,7 +87,7 @@
"style": {
"navigationStyle": "custom"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -96,7 +96,7 @@
"style": {
"navigationStyle": "custom"
},
- "meta":{
+ "meta": {
"isAuth": true
}
},
@@ -489,6 +489,15 @@
"style": {
"navigationBarTitleText": "Animation 动画"
}
+ },
+ {
+ "path": "other/router/index",
+ "style": {
+ "navigationBarTitleText": "Router 路由"
+ }
+ },
+ {
+ "path": "other/router/query"
}
]
},
@@ -512,6 +521,9 @@
"style": {
"navigationBarTitleText": "收货地址",
"enablePullDownRefresh": true
+ },
+ "meta": {
+ "isAuth": true
}
},
{
diff --git a/pages/demo/other/router/index.uvue b/pages/demo/other/router/index.uvue
new file mode 100644
index 0000000..296823e
--- /dev/null
+++ b/pages/demo/other/router/index.uvue
@@ -0,0 +1,41 @@
+
+
+
+
+ {{ t("跳转") }}
+
+
+
+ {{ t("跳转") }}
+
+
+
+ {{ t("跳转") }}
+
+
+
+
+
+
+
+
diff --git a/pages/demo/other/router/query.uvue b/pages/demo/other/router/query.uvue
new file mode 100644
index 0000000..de14587
--- /dev/null
+++ b/pages/demo/other/router/query.uvue
@@ -0,0 +1,29 @@
+
+
+
+
+ {{ id ?? "-" }}
+
+
+
+ {{ userInfo?.nickName ?? "-" }}
+
+
+
+
+
+
+
+
diff --git a/pages/index/home.uvue b/pages/index/home.uvue
index b55c4b0..7d49472 100644
--- a/pages/index/home.uvue
+++ b/pages/index/home.uvue
@@ -46,9 +46,9 @@
- {{
- item.label
- }}({{ item.children?.length ?? 0 }})
+ {{ item.label }}({{ item.children?.length ?? 0 }})
@@ -461,6 +461,11 @@ const data = computed- (() => {
label: "Animation",
icon: "instance-line",
path: "/pages/demo/other/animation"
+ },
+ {
+ label: "Router",
+ icon: "compass-discover-line",
+ path: "/pages/demo/other/router/index"
}
]
}
diff --git a/router/index.ts b/router/index.ts
index c5a4624..9fca840 100644
--- a/router/index.ts
+++ b/router/index.ts
@@ -1,8 +1,17 @@
import { router, useStore } from "@/cool";
-router.beforeEach((to, _, next) => {
+/**
+ * 路由跳转前的全局钩子(如修改 pages.json 后需重新编译项目以确保路由信息生效)
+ * @param to 跳转页
+ * @param from 当前页
+ * @param next 跳转函数
+ */
+router.beforeEach((to, from, next) => {
const { user } = useStore();
- if (to.meta?.isAuth == true) {
+
+ // 判断是否需要登录
+ if (to.isAuth == true || to.meta?.isAuth == true) {
+ // 如果用户信息为空,则跳转到登录页
if (!user.isNull()) {
next();
} else {
@@ -11,4 +20,4 @@ router.beforeEach((to, _, next) => {
} else {
next();
}
-});
\ No newline at end of file
+});