2026-09-09 22:05:00 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* NavBar 自定义导航栏(规范 §17)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 用于非 tabBar 页面:返回按钮 + 标题 + 右侧操作 slot。
|
2026-09-23 09:55:40 +08:00
|
|
|
|
*
|
|
|
|
|
|
* 顶部几何(2026-09-23 修正):
|
|
|
|
|
|
* 此前 statusBarHeight / navBarHeight 由调用方各自用 wx.getSystemInfoSync 估算
|
|
|
|
|
|
* (`platform === 'android' ? 48 : 44`),**从未读取右上角胶囊按钮的真实位置**。
|
|
|
|
|
|
* 后果:导航行与胶囊不在同一水平带;右侧 slot 内容(如 chat 页的「⋯」)直接压在
|
|
|
|
|
|
* 胶囊下面点不到。现改为组件自己调 utils/nav-metrics 实测胶囊矩形:
|
|
|
|
|
|
* - 导航行高度与胶囊垂直居中对齐;
|
|
|
|
|
|
* - 标题居中且用 max-width 让开胶囊(左右对称,仍精确居中于屏幕);
|
|
|
|
|
|
* - 右侧 slot 内缩 --nav-right,整体落在胶囊左侧。
|
|
|
|
|
|
* 调用方传入的 statusBarHeight / navBarHeight 仅作为「拿不到胶囊信息」时的兜底,
|
|
|
|
|
|
* 不再作为唯一事实源(旧页面无需改动)。
|
|
|
|
|
|
*
|
2026-09-09 22:05:00 +08:00
|
|
|
|
* 用法:
|
|
|
|
|
|
* <ui-nav-bar title="编辑资料" show-back bind:back="onBack" />
|
2026-09-23 09:55:40 +08:00
|
|
|
|
* <ui-nav-bar title="聊天"><view slot="right">⋯</view></ui-nav-bar>
|
2026-09-09 22:05:00 +08:00
|
|
|
|
*/
|
2026-09-23 09:55:40 +08:00
|
|
|
|
const { getNavMetrics } = require('../../utils/nav-metrics');
|
|
|
|
|
|
|
2026-09-09 22:05:00 +08:00
|
|
|
|
Component({
|
|
|
|
|
|
options: { addGlobalClass: true, multipleSlots: true },
|
|
|
|
|
|
properties: {
|
|
|
|
|
|
title: { type: String, value: '' },
|
|
|
|
|
|
showBack: { type: Boolean, value: true },
|
2026-09-23 09:55:40 +08:00
|
|
|
|
statusBarHeight: { type: Number, value: 0 },
|
|
|
|
|
|
navBarHeight: { type: Number, value: 0 },
|
2026-09-09 22:05:00 +08:00
|
|
|
|
bg: { type: String, value: 'card' }, // card | transparent
|
|
|
|
|
|
},
|
|
|
|
|
|
data: {
|
|
|
|
|
|
containerStyle: '',
|
2026-09-23 09:55:40 +08:00
|
|
|
|
navVars: '',
|
|
|
|
|
|
},
|
|
|
|
|
|
lifetimes: {
|
|
|
|
|
|
attached() {
|
|
|
|
|
|
this.applyNavMetrics();
|
|
|
|
|
|
},
|
2026-09-09 22:05:00 +08:00
|
|
|
|
},
|
|
|
|
|
|
observers: {
|
2026-09-23 09:55:40 +08:00
|
|
|
|
// 调用方 setData 后重算(旧页面习惯在 onLoad 里注入,可能晚于组件初次渲染)
|
|
|
|
|
|
'statusBarHeight, navBarHeight'() {
|
|
|
|
|
|
this.applyNavMetrics();
|
2026-09-09 22:05:00 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-09-23 09:55:40 +08:00
|
|
|
|
applyNavMetrics() {
|
|
|
|
|
|
const metrics = getNavMetrics();
|
|
|
|
|
|
const measured = metrics.source === 'capsule';
|
|
|
|
|
|
// 实测到胶囊时以实测为准;否则回落到调用方传入值,再回落到兜底值
|
|
|
|
|
|
const statusBar = measured
|
|
|
|
|
|
? metrics.statusBarHeight
|
|
|
|
|
|
: (this.properties.statusBarHeight || metrics.statusBarHeight);
|
|
|
|
|
|
const navBar = measured
|
|
|
|
|
|
? metrics.navBarHeight
|
|
|
|
|
|
: (this.properties.navBarHeight || metrics.navBarHeight);
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
containerStyle: `padding-top: ${statusBar}px; height: ${statusBar + navBar}px;`,
|
|
|
|
|
|
navVars: `--nav-h: ${navBar}px; --nav-right: ${metrics.reserve}px;`,
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
2026-09-09 22:05:00 +08:00
|
|
|
|
onBack() {
|
|
|
|
|
|
this.triggerEvent('back', {});
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|