导航系统
概述
导航系统提供了统一的页面导航和路由管理功能。
核心概念
路由注册
在模块中注册路由:
typescript
/**
* 用户模块
* 实现 FeatureModule 接口,支持自动注册
*/
export class UserModule implements FeatureModule {
/**
* 注册路由
* @param registry 路由注册器
*/
registerRoutes(registry: RouteRegistry): void {
// 注册用户页路由
registry.register(UserRoutes.Profile, profileNavBuilderWrapper);
}
}页面导航
使用 NavigationService 进行页面导航:
typescript
import { NavigationService } from "@core/navigation";
// 导航到指定页面
NavigationService.push("user/profile", { userId: "123" });
// 返回上一页
NavigationService.pop();
// 替换当前页面
NavigationService.replace("user/settings");
// 返回到根页面
NavigationService.popToRoot();路由参数
传递参数
typescript
NavigationService.push("user/profile", {
userId: "123",
from: "main"
});接收参数
typescript
@Entry
@Component
struct UserProfilePage {
@State userId: string = "";
aboutToAppear(): void {
// 获取路由参数
const params = NavigationService.getParams();
this.userId = params.userId;
}
build() {
Column() {
Text(`用户 ID: ${this.userId}`);
}
}
}路由拦截
登录拦截
typescript
NavigationService.addInterceptor((to, from) => {
if (to.path.startsWith("user/") && !isLoggedIn()) {
// 未登录,跳转到登录页
NavigationService.push("auth/login");
return false; // 阻止导航
}
return true; // 允许导航
});权限拦截
typescript
NavigationService.addInterceptor((to, from) => {
const requiredPermission = to.meta?.permission;
if (requiredPermission && !hasPermission(requiredPermission)) {
// 无权限,显示提示或跳转到无权限页面
showToast("您没有访问权限");
return false;
}
return true;
});全局拦截器
typescript
// 添加全局前置拦截器
NavigationService.beforeEach((to, from, next) => {
console.log(`导航从 ${from.path} 到 ${to.path}`);
// 检查登录状态
if (to.meta?.requiresAuth && !isLoggedIn()) {
next({ path: "auth/login", query: { redirect: to.path } });
return;
}
// 检查权限
if (to.meta?.permission && !hasPermission(to.meta.permission)) {
showToast("无权限访问");
next(false);
return;
}
next();
});
// 添加全局后置拦截器
NavigationService.afterEach((to, from) => {
// 记录页面访问日志
logPageView(to.path);
// 更新页面标题
document.title = to.meta?.title || "默认标题";
});路由守卫
typescript
/**
* 认证模块
* 实现 FeatureModule 接口,支持自动注册
*/
export class AuthModule implements FeatureModule {
/**
* 注册路由守卫
* @param navigationService 导航服务
*/
registerGuards(navigationService: NavigationService): void {
// 注册认证守卫(保护需要登录的页面)
navigationService.registerGuard(new AuthGuard());
}
}
/**
* 认证路由守卫
* 保护需要登录才能访问的页面
*/
class AuthGuard implements RouteGuard {
/**
* 守卫名称
*/
readonly name: string = 'AuthGuard';
/**
* 守卫优先级(数字越大优先级越高)
*/
readonly priority: number = 100;
/**
* 检查是否可以激活路由
* @param context 路由上下文
* @returns 是否允许导航
*/
canActivate(context: RouteContext): boolean | Promise<boolean> {
return false;
}
/**
* 守卫拒绝时的回调
* @param context 路由上下文
* @param result 守卫结果
*/
onReject(context: RouteContext, result: GuardResult): void {
// 跳转到登录页
}
}最佳实践
1. 统一路由管理
在模块初始化时统一注册路由:
typescript
/**
* 用户模块
* 实现 FeatureModule 接口,支持自动注册
*/
export class UserModule implements FeatureModule {
/**
* 注册路由
* @param registry 路由注册器
*/
registerRoutes(registry: RouteRegistry): void {
// 注册用户页路由
registry.register(UserRoutes.Profile, profileNavBuilderWrapper);
}
/**
* 注册路由守卫
* @param navigationService 导航服务
*/
registerGuards(navigationService: NavigationService): void {
// 用户模块不需要额外的守卫,依赖 auth 模块的认证守卫
}
}2. 路由命名规范
使用 模块名/页面名 的格式命名路由:
typescript
// 推荐
"user/profile"
"auth/login"
"main/home"
// 不推荐
"profile"
"login"
"home"3. 参数类型安全
定义参数接口确保类型安全:
typescript
interface UserProfileParams {
userId: string;
from?: string;
}
NavigationService.push<UserProfileParams>("user/profile", {
userId: "123",
from: "main"
});注意事项
- 路由注册:确保在使用前注册路由
- 参数传递:注意参数的类型和必填性
- 内存管理:及时清理不需要的页面栈