鸿蒙ASCF app.json pages到tabBar配置踩坑
在鸿蒙元服务(ASCF)开发中,app.json 是每个工程最先接触的全局配置文件。页面路由、窗口样式、底部 Tab、分包结构等都由它控制。文档里有些字段写得比较简略,实际配置时容易踩坑。本文结合实践把 app.json 的完整配置项过一遍,并整理需要注意的细节。一、pages 与 entryPagePath:页面路由表
pages 是必填配置,第一项就是默认启动页面。路径不需要写文件后缀名,系统会自动查找对应的 .hxml 文件。例如:
{
"pages": [
"page/index/index",
"page/API/pages/make-phone-call/make-phone-call",
"page/API/pages/share-api/share-api"
]
}
如果不想用第一项作为首页,可以通过 entryPagePath 覆盖,但注意不能带页面参数。
需要特别留意的是 pages 数组的顺序。它不只是路由表,第一项直接决定默认启动页。如果不写 entryPagePath,删掉或重排 pages 中的第一项,首页就会跟着变。笔者第一次重排页面顺序时,就把首页搞乱了。
二、window:窗口与导航栏配置
window 控制全局导航栏和窗口样式,常见配置如下:
{
"window": {
"navigationBarBackgroundColor": "#0A59F7",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "我的元服务",
"navigationStyle": "default",
"backgroundColor": "#f5f5f5",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
}
这里有几个注意点:
navigationBarTextStyle 在 API 12 时限制较多:custom 模式下可以设置 black/white,default 模式只能 black。API 13 及以上才都支持。
navigationStyle 设为 custom 会隐藏导航栏,但右上角的胶囊按钮仍然保留。同时页面顶部会多出状态栏高度的空白区域,需要自己处理,否则页面内容会被状态栏挡住。
onReachBottomDistance 的单位是 px 而不是 dp,在低分辨率设备上触底距离看起来会不一样。
三、tabBar:底部 Tab 栏配置
tabBar 用于配置底部导航,示例:
{
"tabBar": {
"color": "#999999",
"selectedColor": "#0A59F7",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"position": "bottom",
"custom": false,
"list": [
{
"pagePath": "page/index/index",
"text": "首页",
"iconPath": "image/tab/home.png",
"selectedIconPath": "image/tab/home-active.png"
},
{
"pagePath": "page/API/index",
"text": "API",
"iconPath": "image/tab/api.png",
"selectedIconPath": "image/tab/api-active.png"
}
]
}
}
实际踩坑记录如下:
图标限制 40kb,图片太大不会显示。一开始没有使用工具自带的图标,自己切图结果超了,排查半天。
tabBar 页面必须在主包中,不能放在分包里。文档虽然写了,但很容易忽略。笔者分包写好后发现 tabBar 页面跳转不了,折腾了很久。
颜色支持十六进制,简写(如 #fff)其实也支持,但建议写完整六位,避免不同平台解析差异。
另外,list 中的 pagePath 必须在 pages 数组中有对应路径,否则 tabBar 页面会报错跳转不了。
四、subpackages:分包配置
分包可以把页面按功能拆分,减少首屏加载体积。示例:
{
"subpackages": [
{
"resource": "packageMore",
"root": "packageMore",
"pages": [
"more/more",
"detail/detail"
]
}
]
}
分包后的路径写法保持不变,但编译后只会保留 pages 字段,其他字段对齐。注意 tabBar 页面不能被分到子包中。
五、resolveAlias:模块路径别名
当页面层级较深时,长长的相对路径写起来很痛苦。resolveAlias 可以给模块路径起别名:
{
"resolveAlias": {
"~/*": "/*",
"~/index/*": "index/*",
"@utils/*": "utils/*",
"subBView/*": "subpackageB/view/*"
}
}
配置之后,代码里就可以这样引用:
// 不用再写 ../../../utils/test.js
const { formatDate } = require('@utils/test');
使用 resolveAlias 有两点限制:
key 和 value 都必须以 /* 结尾,少了结尾通配符会导致匹配失败。
如果多条规则同时匹配,会选取最长的规则映射,需要注意优先级。
该能力需要 ASCF Toolkit 版本不低于 1.0.4。
六、lazyCodeLoading:代码按需注入
lazyCodeLoading 可以配置自定义组件代码按需注入,目前只支持 requiredComponents:
{
"lazyCodeLoading": "requiredComponents"
}
配置后,只有页面真正用到的组件才会被加载,有助于减少首屏体积。该配置起始版本为 1.0.13,Toolkit 需要不低于 1.0.6。
七、后台运行与隐私保护
如果元服务需要在后台运行(目前仅支持后台音乐播放 audio),可以这样声明:
{
"requiredBackgroundModes": ["audio"]
}
另外,从 2.0.1 版本开始,支持 visualEffectInBackground 配置,用于切入后台时隐藏页面内容,防止敏感信息泄露:
{
"visualEffectInBackground": "hidden"
}
该字段支持 none(不处理)和 hidden(隐藏内容)两个值。金融类元服务建议开启 hidden。
八、实际项目配置示例
下面是一个实际项目中的 app.json 配置,综合了上述常用配置项:
{
"pages": [
"page/index/index",
"page/API/index",
"page/API/pages/share-api/share-api",
"page/API/pages/make-phone-call/make-phone-call",
"page/API/pages/battery/battery",
"page/API/pages/accelerometer/accelerometer",
"page/API/pages/gyroscope/gyroscope"
],
"window": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "ASCF 演示",
"backgroundColor": "#f5f5f5",
"backgroundTextStyle": "dark"
},
"tabBar": {
"color": "#999999",
"selectedColor": "#0A59F7",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "page/index/index",
"text": "首页",
"iconPath": "image/tab/home.png",
"selectedIconPath": "image/tab/home-active.png"
},
{
"pagePath": "page/API/index",
"text": "API",
"iconPath": "image/tab/api.png",
"selectedIconPath": "image/tab/api-active.png"
}
]
},
"resolveAlias": {
"@utils/*": "utils/*",
"@components/*": "components/*"
}
}
九、避坑清单总结
结合上述配置,最需要记住的坑有:
pages 顺序决定默认首页,重排时务必确认 entryPagePath。
tabBar 的 pagePath 必须与 pages 对应,且 tabBar 页面必须在主包。
tabBar 图标大小不能超过 40kb,否则不显示。
navigationStyle: custom 会带来状态栏遮挡问题,需要自行适配。
resolveAlias 的 key/value 必须以 /* 结尾,多规则匹配时按最长规则生效。
visualEffectInBackground 只在 2.0.1+ 生效,低版本不报错但不生效。
app.json 的配置项不算复杂,但很多错误不会直接报错,而是表现为页面显示异常,排查起来比较费时间。建议在工程初始化时就把这些字段确认好,避免后期返工。
Re: 鸿蒙ASCF app.json pages到tabBar配置踩坑
感谢楼主分享,这几个坑确实很典型。尤其tabBar图标大小限制和分包问题,当时我也折腾了好久。补充一个小细节:pages数组顺序影响默认首页这点,如果不小心重排了,确实容易一脸懵。另外navigationStyle设为custom后状态栏高度处理,建议用系统提供的安全区接口动态计算,避免写死。希望后面还能看到更多ASCF实战经验贴,加油!Re: 鸿蒙ASCF app.json pages到tabBar配置踩坑
感谢分享,这几个坑都很真实。特别是 tabBar 图标 40kb 限制和分包不能放 tabBar 页面,新手很容易中招。还有 navigationStyle custom 后状态栏空白要自己处理,这个官方文档确实没细说。收藏了,下次配 app.json 可以少走弯路。Re: 鸿蒙ASCF app.json pages到tabBar配置踩坑
感谢分享,这篇把 app.json 的坑基本都点到了。特别是 tabBar 页面不能放分包那个,我当初也卡了好久,明明路径没错但就是跳不过去,后来翻文档才发现是分包的限制。还有图标 40kb 的限制确实容易忽略,自己切的图稍微大点就不显示了,折腾半天还以为是路径写错。 另外补充一个自己遇到的小细节:`entryPagePath` 虽然能指定首页,但 pages 数组第一项最好还是保持和实际首页一致,不然有时候 IDE 预览或调试工具会默认打开 pages 第一项,容易误导。还有 `onReachBottomDistance` 那个 px 单位的坑,确实在真机上不同分辨率表现不一样,调的时候建议用相对值或者直接固定距离多测几台设备。 总之 app.json 虽然看着简单,但细节真的不少,楼主的整理很实用。
页:
[1]