场景描述
在应用开发中无论是出于工程组织效率还是开发体验的考虑,开发者都需要对项目进行模块间解耦,此时需要构建一套用于模块间组件跳转、数据通信的路由框架。
业界常见的实现方式是在编译期生成路由表。
1. 实现原理及流程
- 在编译期通过扫描并解析ets文件中的自定义注解来生成路由表和组件注册类
- Har中的rawfile文件在Hap编译时会打包在Hap中,通过这一机制来实现路由表的合并
- 自定义组件通过wrapBuilder封装来实现动态获取
- 通过NavDestination的Builder机制来获取wrapBuilder封装后的自定义组件
2. 使用ArkTS自定义装饰器来代替注解的定义
由于TS语言特性,当前只能使用自定义装饰器
使用@AppRouter装饰器来定义路由信息
// 定义空的装饰器
export function AppRouter(param:AppRouterParam) {
return Object;
}
export interface AppRouterParam{
uri:string;
}
自定义组件增加路由定义
@AppRouter({
uri: "app://login" })
@Component
export struct LoginView {
build(){
//...
}
}
3. 实现动态路由模块
定义路由表(该文件为自动生成的路由表)
{
"routerMap": [
{
"name": "app://login", /* uri定义 */
"pageModule": "loginModule", /* 模块名 */
"pageSourceFile": "src/main/ets/generated/RouterBuilder.ets", /* Builder文件 */
"registerFunction": "LoginViewRegister" /* 组件注册函数 */
}
]
}
应用启动时,在EntryAbility.onCreate中加载路由表
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
DynamicRouter.init({
libPrefix: "@app", mapPath: "routerMap"
}, this.context);
}
export class DynamicRouter {
// 路由初始化配置
static config: RouterConfig;
// 路由表
static routerMap: Map<string, RouterInfo> = new Map();
// 管理需要动态导入的模块,key是模块名,value是WrappedBuilder对象,动态调用创建页面的接口
static builderMap: Map<string, WrappedBuilder<Object[]>> = new Map();
// 路由栈
static navPathStack: NavPathStack = new NavPathStack();
// 通过数组实现自定义栈的管理
static routerStack: Array<RouterInfo> = new Array();
static referrer: string[] = [];
public static init(config: RouterConfig, context: Context) {
DynamicRouter.config = config;
DynamicRouter.routerStack.push(HOME_PAGE)
RouterLoader.load(config.mapPath, DynamicRouter.routerMap, context)
}
//...
}
路由表存放在src/main/resources/rawfile目录中,通过ResourceManager进行读取
export namespace RouterLoader {
export function load(dir

最低0.47元/天 解锁文章

1031

被折叠的 条评论
为什么被折叠?



