- aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效
- onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效
- onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行
- onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)
- onShown:NavDestination组件布局显示之后执行,此时页面已完成布局
- onActive: NavDestination处于激活态(处于栈顶可操作,且上层无特殊组件遮挡)触发
- onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)
- onInactive: NavDestination组件处于非激活态(处于非栈顶不可操作,或处于栈顶时上层有特殊组件遮挡)触发
- onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)
- onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)
- onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行
- aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量
注意toolbarConfiguration 和 menus 的图标注意路径:'icon': "resources/base/media/ic_public_highlights.svg"
或./image/ic_public_highlights.svg
,涉及到 icon 图图标类的路径都需要这么写
对象名: NavPathStack = new NavPathStack() Navigation(this.对象名){ //内容.... } //.size({width: '数字%', height: '数字%'}) .size({width: 数字, height: 数字}) .title('标题栏文字') .titleMode(NavigationTitleMode.枚举值) //设置标题模式 .subTitle("副标题文字") .backButtonIcon(图片格式) //设置返回图标 .hideTitleBar(true) //隐藏标签栏,false:不隐藏 .hideToolBar(false) //隐藏工具栏 .hideBackButton(true) //隐藏返回按钮 .mode(NavigationMode.Stack) //强制让 Navigation单栏布局 .toolbarConfiguration([{ //底部工具栏 value: "Save", 'icon': "resources/base/media/ic_public_highlights.svg", action: () => console.log("Saved!") //点击事件 }]) // 竖屏最多支持显示3个图标,多余的图标会被放入自动生成的更多图标 .menus([ //标题栏右上角的菜单项 { value: "搜索", icon: "resources/base/media/ic_public_highlights.svg", action: () => { //点击事件 console.log("搜索") } } ])
|
在**src/main/resources/base/profile**
创建 route_map.json 编写
{ "routerMap": [ { "name": "页面标识", //子页面唯一标识 "pageSourceFile": "src/main/ets/pages/ziyemian/PageOne.ets", //子页面路径 "buildFunction": "函数名", //子页面入口函数,必须以@Builder修饰 "data": { //描述、权限等扩展信息 "description": "this is pageOne" } } ] }
|
在module.json5
添加路由:
"routerMap": "$profile:route_map", //添加路由
|
数据传递:通过页面标识传递的,所以不局限于一传二,二传三页面,可以在任意子页面接收到数据
//传递单个字符 MKNavPathStack.pushPathByName('子页面标识', 传入的字符变量名); NavDestination() { } .onReady((context: NavDestinationContext) => { const pathStack = context.pathStack const deviceIdList = pathStack.getParamByName('子页面标识') as string[] if (deviceIdList && deviceIdList.length > 0) { const deviceId = deviceIdList[deviceIdList.length - 1] this.mqtt_info.serverID = deviceId console.log("收到 deviceId: " + deviceId) } })
//传递多个 export interface DHTInfoParams { deviceId: string; deviceName: string; linkMode: string; linkstatus: string; icon: Resource; } const params: DHTInfoParams = { deviceId: item.deviceViewId, deviceName: item.deviceName, linkstatus: item.linkstatus, icon: getIconByType(item.deviceType), linkMode: item.pipeline, }; MKNavPathStack.pushPathByName('子页面标识', params) NavDestination() { } .onReady((context: NavDestinationContext) => { //获取主页面传递的参数 const pathStack = context.pathStack const paramsArray = pathStack.getParamByName('子页面标识') as DHTInfoParams[] if (paramsArray && paramsArray.length > 0) { const param = paramsArray[paramsArray.length - 1] // 取栈顶的那个 this.params.deviceId = param.deviceId this.params.deviceName = param.deviceName this.params.icon = param.icon this.params.linkMode = param.linkMode this.params.linkstatus = param.linkstatus console.log("收到参数: " + JSON.stringify(this.params)) this.loadMQTTInfoFromDB() } })
|
数据回传
MKNavPathStack.pushPathByName('MQTTInfoView', this.params.deviceId, (info: PopInfo) => { this.mqtt_id = info.result.toString() console.log('回传MQTT的ID:', this.mqtt_id) });
MKNavPathStack.pop(res.data.data.id);
|
跳转
this.对象名.pushPath({name: '子页面标识'}) this.对象名.pushPathByName('子页面标识', null)
|
返回回调(物理&按钮)
NavDestination() { } .onBackPressed(()=>{ promptAction.openToast({message:"返回了"}) return true })
|
替换,不能返回上一页
this.对象名.replacePath({'子页面标识'}) this.对象名.replacePathByName('子页面标识', null)
|
页面返回
// 返回到上一页 this.对象名.pop() // 返回到上一个PageOne页面 this.对象名.popToName("子页面标识") // 返回到索引为1的页面 this.对象名.popToIndex(1) // 返回到根首页(清除栈中所有页面) this.对象名.clear()
|
页面删除
// 删除栈中name为PageOne的所有页面 this.对象名.removeByName("子页面标识") // 删除指定索引的页面 this.对象名.removeByIndexes([1,3,5]) // 删除指定id的页面 this.对象名.removeByNavDestinationId("1");
|
跳转的页面,因为跳转的页面入口必须是 Builder 修饰的全局函数
@Builder export function 函数名() { //这里的函数名必须和route_map.json中的buildFunction一致 跳转页面入口函数 } NavDestination() {} //页面展示必须在这个包裹里面才可以展示
|
路由拦截
@Entry @Component struct NavigationAPI9 { build() { Navigation() { //router具备跳转能力 NavRouter() { //跳转组件 - 只能放置一个组件------------------------------1 // 第二个会覆盖第一个 Button('跳转A') Button('跳转B') //要跳转的界面-------------------------------------------2 NavDestination() { NavRouter() { // 第一个组件就是点击进行跳转的 Image($r('app.media.b')) .width(100) NavDestination(){ Text('第三个页面') } } } } } } }
|
commons(公共能力层):提供整个应用共享的基础组件、工具类、公共配置等,如公共UI组件、数据管理、网络请求封装等,通常编译为HAR包或HSP包
features(基础特性层):实现应用的各个功能模块,每个模块相对独立,可单独开发和测试。通常编译为HAR包、HSP包或Feature类型的HAP包
products(产品定制层):针对不同设备形态(如手机、平板等)进行功能和特性集成,是应用的主入口,通常编译为Entry类型的HAP包
三层架构示例代码.zip
寻找包名:\project01\AppScope\app.json5
中的 bundleName
- 在工程目录下,创建三个文件夹commons、features、products

- 实现首页、课程学习、知识地图这三个功能页面,创建feature模块 quickstart、map、learning,选择Shared Library
- 创建commons层模块,创建两个模块utils和uicomponents,选择Static Library
具体使用Static Library 还是 **Shared Library **还需要根据实际情况 文档中心
Module类型 |
包类型 |
说明 |
Ability |
HAP |
应用的功能模块,可以独立安装和运行,必须包含一个entry类型的HAP,可选包含一个或多个feature类型的HAP。 |
Static Library |
HAR |
静态共享包,编译态复用。 - 支持应用内共享,也可以发布后供其他应用使用。 - 作为二方库,发布到OHPM私仓,供公司内部其他应用使用。 - 作为三方库,发布到OHPM中心仓,供其他应用使用。 - 多包(HAP/HSP)引用相同的HAR时,会造成多包间代码和资源的重复拷贝,从而导致应用包膨大。 - 注意:编译HAR时,建议开启混淆能力,保护代码资产。 |
Shared Library |
HSP |
动态共享包,运行时复用。 - 当前仅支持应用内共享。 - 当多包(HAP/HSP)同时引用同一个共享包时,采用HSP替代HAR,可以避免HAR造成的多包间代码和资源的重复拷贝,从而减小应用包大小。 |
模块导出,无论是 **Static Library **或 **Shared Library **都是同样的,引用 HSP 资源: 文档中心,HAR 不需要引用因为是复制包,直接使用即可
对应的页面需要导出
@Entry @Component export struct SingSongPage { @State message: string = 'SingSongPage';
build() { Row() { Column() { Text(this.message) .fontSize($r('app.float.page_text_font_size')) .fontWeight(FontWeight.Bold) .onClick(() => { this.message = 'Welcome'; }) } .width('100%') } .height('100%') } }
|
当前的文件夹新建 index.ets,导出对应模块文件 
export *from './SingSongPage'
|
然后在 features 或 common 根目录下有个 Index.ets 中也需要导出 
export { add } from './src/main/ets/utils/Calc'; export * from './src/main/ets/pages'
|
导入之后在入口 products 还需要导入,
"dependencies": { "singsong": "file:../../features/SingSong" }
|
在products 中使用 router 跳转模块不能使用常规的路径跳转
router.pushUrl({ //@bundle:包名/模块名/路径 url:'@bundle:com.xinzai.myapplication/SingSong/ets/pages/SingSongPage' })
|
使用 navigation 跳转
@Entry @Component struct NavigationPage { navPathStack:NavPathStack =new NavPathStack()
build() { Navigation(this.navPathStack){ Button('跳转') .onClick(()=>{ this.navPathStack.pushPath({name: 'singsong' }) }) }.height('100%').width('100%') } }
|
src/main/ets/pages/builders/HspBuilder.ets
import { SingSongPage } from 'singsong'
@Builder function HspBuilder(){ NavDestination(){ SingSongPage() } }
|
src/main/resources/base/profile/route_map.json
{ "routerMap": [ { "name": "singsong", "pageSourceFile": "src/main/ets/pages/builders/HspBuilder.ets", "buildFunction": "HspBuilder", "data": { "description": "this is pageOne" } } ] }
|
封装工具
API封装工具.zip
数据库操作封装.zip
首选项工具封装.zip
MQTT工具封装.zip
加载弹窗动画封装.zip