From 6d49d28e1a66f0130051435650e860faa7a777ba Mon Sep 17 00:00:00 2001 From: Blizzard Date: Thu, 30 Jul 2026 08:22:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(fe):=20=E4=BF=AE=20Phase=20D=20=E4=B8=89?= =?UTF-8?q?=E4=B8=AA=E6=B8=B2=E6=9F=93=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 1. tabBar 高亮不跟着切(进「我的」还亮在「首页」) Phase A 我把高亮改成 custom-tab-bar 自己在 pageLifetimes.show 里按路由算, 想省掉五个页面的硬编码。实测不行:自定义 tabBar 不在页面节点树里, pageLifetimes 拿不到可靠时机,selected 一直停在默认的 0。 回到官方那套「页面 onShow 推一把」,但索引仍然由 tabBar 按当前路由自己算 (utils/tabbar.js → syncSelected),页面这边不写死 0/1/2/3/4。 调 tab 顺序还是只改一个 LIST,五个页面一行都不用动——原来想要的收益保住了, 只是多了五行 syncTabBar(this)。 ## 2. 头像被头图盖住,只露出下半个 .pf-bg 带了 position:relative,定位元素会盖过静态的兄弟节点,DOM 顺序在后 也没用。给 .pf-av 加 position:relative + z-index,同时把 .pf-bg 上那个没人 用的 position 去掉。头图高度 220 → 180rpx,纯渐变时不至于占掉半屏。 ## 3.「我的」页四个入口整个散架,图标文字箭头各占一行 .profile-list / .profile-row / .pr-ic / .pr-label / .pr-val 全在 settings.wxss 里——Phase A 从 profile 拆页时留在了设置页,mine 用同一批 class 但样式跨不了页,于是完全裸奔。提到 app.wxss。 这是这个项目第二次踩「页面级 wxss 跨页用」了(上次是 .post-card 在用户 主页裸奔)。两个页面共用的 class 就不该留在任一页的 wxss 里。 Co-Authored-By: Claude Opus 5 --- pets-fe/app.wxss | 17 +++++++++++++++++ pets-fe/components/profile-head/index.wxss | 4 +++- pets-fe/custom-tab-bar/index.js | 19 ++++++++----------- pets-fe/pages/community/community.js | 2 ++ pets-fe/pages/home/home.js | 2 ++ pets-fe/pages/mine/mine.js | 2 ++ pets-fe/pages/record/record.js | 2 ++ pets-fe/pages/report/report.js | 2 ++ pets-fe/pages/settings/settings.wxss | 14 -------------- pets-fe/utils/tabbar.js | 14 ++++++++++++++ 10 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 pets-fe/utils/tabbar.js diff --git a/pets-fe/app.wxss b/pets-fe/app.wxss index fc9160a..780d74b 100644 --- a/pets-fe/app.wxss +++ b/pets-fe/app.wxss @@ -402,3 +402,20 @@ page{scrollbar-width:none;-ms-overflow-style:none} /* 分享用微信原生 open-type=share,得抹掉 button 默认外观 */ .pa-share{background:transparent;border:none;padding:0;margin:0;line-height:inherit} .pa-share::after{border:none} + +/* ===== 设置项列表 ===== + settings 和 mine 都在用。页面级 wxss 跨不了页,放在任一页里另一页就是裸的 */ +.profile-list{background:#fff;border-radius:var(--r-lg);box-shadow:var(--sd-1);overflow:hidden;margin-bottom:var(--sp-4)} +.profile-row{ + display:flex;align-items:center;gap:var(--sp-3);min-height:104rpx;padding:0 var(--sp-4); + border-bottom:1rpx solid var(--line);font-size:var(--fs-md);font-weight:var(--fw-b); +} +.profile-row:last-child{border-bottom:0} +.pr-ic{ + width:56rpx;height:56rpx;border-radius:var(--r-xs);flex:none; + display:flex;align-items:center;justify-content:center; + background:var(--primary-soft);color:var(--primary-ink); +} +.pr-label{flex:1;min-width:0} +.pr-val{color:var(--muted);font-weight:var(--fw);font-size:var(--fs-sm)} +.pr-arrow{color:var(--muted2);display:flex;align-items:center;flex:none} diff --git a/pets-fe/components/profile-head/index.wxss b/pets-fe/components/profile-head/index.wxss index 85c6657..8c268d6 100644 --- a/pets-fe/components/profile-head/index.wxss +++ b/pets-fe/components/profile-head/index.wxss @@ -11,12 +11,14 @@ background:#fff;border-radius:var(--r-lg);overflow:hidden; box-shadow:var(--sd-1);margin-bottom:var(--sp-5); } -.pf-bg{height:220rpx;background:linear-gradient(135deg,var(--pf-a),var(--pf-b));position:relative} +.pf-bg{height:180rpx;background:linear-gradient(135deg,var(--pf-a),var(--pf-b))} .pf-bg-img{width:100%;height:100%;display:block} .pf-body{padding:0 var(--sp-5) var(--sp-5);text-align:center} /* 头像压在头图上,负 margin 提上去一半 */ .pf-av{ + /* 必须定位:头像要压在头图上面,靠 DOM 顺序不够——只要头图是定位元素就会反盖过来 */ + position:relative;z-index:1; width:144rpx;height:144rpx;margin:-72rpx auto var(--sp-3); border-radius:50%;background:var(--pf-b);color:var(--pf-ink); display:flex;align-items:center;justify-content:center; diff --git a/pets-fe/custom-tab-bar/index.js b/pets-fe/custom-tab-bar/index.js index 9fa8591..0a44bfd 100644 --- a/pets-fe/custom-tab-bar/index.js +++ b/pets-fe/custom-tab-bar/index.js @@ -8,27 +8,24 @@ const LIST = [ Component({ data: { selected: 0, hidden: false, list: LIST }, - // 高亮由当前页面路径自己算出来。 - // 原来每个 tab 页在 onShow 里硬写 selected: 0/1/2/3/4,调一次顺序就要同时改 - // 五个文件,漏一个就高亮错位——这次把计划换成我的正好会踩到。 - pageLifetimes: { - show() { - this.syncSelected(); - }, - }, lifetimes: { attached() { this.syncSelected(); }, }, methods: { + // 高亮由当前页面路径算出来,页面那边不写死 0/1/2/3/4, + // 调 tab 顺序只改上面的 LIST 就够了。 + // + // 触发时机必须由页面 onShow 推(见 utils/tabbar.js):自定义 tabBar 不在 + // 页面节点树里,组件自己的 pageLifetimes.show 拿不到可靠时机,实测切到 + // 「我的」时高亮还留在「首页」。 syncSelected() { const pages = getCurrentPages(); const cur = pages[pages.length - 1]; if (!cur) return; - const path = '/' + cur.route; - const i = LIST.findIndex((t) => t.pagePath === path); - if (i >= 0 && i !== this.data.selected) this.setData({ selected: i }); + const i = LIST.findIndex((t) => t.pagePath === '/' + cur.route); + if (i >= 0) this.setData({ selected: i }); }, switchTab(e) { wx.switchTab({ url: LIST[e.currentTarget.dataset.index].pagePath }); diff --git a/pets-fe/pages/community/community.js b/pets-fe/pages/community/community.js index c4ffc0f..9ae2c2d 100644 --- a/pets-fe/pages/community/community.js +++ b/pets-fe/pages/community/community.js @@ -1,6 +1,7 @@ const store = require('../../utils/store.js'); const api = require('../../utils/api.js'); const { toastErr } = require('../../utils/ui.js'); +const { syncTabBar } = require('../../utils/tabbar.js'); // 相对时间。社区里关心的是「多久以前发的」,精确到秒没意义 function fmtAgo(iso) { @@ -61,6 +62,7 @@ Page({ if (this._unsub) this._unsub(); }, onShow() { + syncTabBar(this); store .ready() .then(() => { diff --git a/pets-fe/pages/home/home.js b/pets-fe/pages/home/home.js index 5df3acc..ef9a255 100644 --- a/pets-fe/pages/home/home.js +++ b/pets-fe/pages/home/home.js @@ -1,6 +1,7 @@ const store = require('../../utils/store.js'); const api = require('../../utils/api.js'); const { toastErr } = require('../../utils/ui.js'); +const { syncTabBar } = require('../../utils/tabbar.js'); function todayStr() { const d = new Date(); @@ -111,6 +112,7 @@ Page({ if (this._unsub) this._unsub(); }, onShow() { + syncTabBar(this); store .ready() .then(() => { diff --git a/pets-fe/pages/mine/mine.js b/pets-fe/pages/mine/mine.js index 5e86611..af5b44d 100644 --- a/pets-fe/pages/mine/mine.js +++ b/pets-fe/pages/mine/mine.js @@ -1,6 +1,7 @@ const store = require('../../utils/store.js'); const api = require('../../utils/api.js'); const { toastErr } = require('../../utils/ui.js'); +const { syncTabBar } = require('../../utils/tabbar.js'); Page({ data: { user: {}, pets: [], card: null, sheetShow: false, sheetType: '' }, @@ -11,6 +12,7 @@ Page({ if (this._unsub) this._unsub(); }, onShow() { + syncTabBar(this); store .ready() .then(() => { diff --git a/pets-fe/pages/record/record.js b/pets-fe/pages/record/record.js index 3a1410e..6302213 100644 --- a/pets-fe/pages/record/record.js +++ b/pets-fe/pages/record/record.js @@ -1,6 +1,7 @@ const store = require('../../utils/store.js'); const api = require('../../utils/api.js'); const { toastErr } = require('../../utils/ui.js'); +const { syncTabBar } = require('../../utils/tabbar.js'); function pad(n) { return n < 10 ? '0' + n : '' + n; @@ -131,6 +132,7 @@ Page({ if (this._unsub) this._unsub(); }, onShow() { + syncTabBar(this); store .ready() .then(() => { diff --git a/pets-fe/pages/report/report.js b/pets-fe/pages/report/report.js index 097f5b7..52e7c7f 100644 --- a/pets-fe/pages/report/report.js +++ b/pets-fe/pages/report/report.js @@ -1,5 +1,6 @@ const store = require('../../utils/store.js'); const api = require('../../utils/api.js'); +const { syncTabBar } = require('../../utils/tabbar.js'); Page({ data: { @@ -22,6 +23,7 @@ Page({ if (this._unsub) this._unsub(); }, onShow() { + syncTabBar(this); store .ready() .then(() => { diff --git a/pets-fe/pages/settings/settings.wxss b/pets-fe/pages/settings/settings.wxss index 8684038..80c2b2e 100644 --- a/pets-fe/pages/settings/settings.wxss +++ b/pets-fe/pages/settings/settings.wxss @@ -9,17 +9,3 @@ .ph-name{font-size:var(--fs-2xl);font-weight:var(--fw-b)} .ph-meta{font-size:var(--fs-sm);margin-top:var(--sp-1)} -.profile-list{background:#fff;border-radius:var(--r-lg);box-shadow:var(--sd-1);overflow:hidden;margin-bottom:var(--sp-4)} -.profile-row{ - display:flex;align-items:center;gap:var(--sp-3);min-height:104rpx;padding:0 var(--sp-4); - border-bottom:1rpx solid var(--line);font-size:var(--fs-md);font-weight:var(--fw-b); -} -.profile-row:last-child{border-bottom:0} -.pr-ic{ - width:56rpx;height:56rpx;border-radius:var(--r-xs);flex:none; - display:flex;align-items:center;justify-content:center; - background:var(--primary-soft);color:var(--primary-ink); -} -.pr-label{flex:1;min-width:0} -.pr-val{color:var(--muted);font-weight:var(--fw);font-size:var(--fs-sm)} -.pr-arrow{color:var(--muted2);display:flex;align-items:center;flex:none} diff --git a/pets-fe/utils/tabbar.js b/pets-fe/utils/tabbar.js new file mode 100644 index 0000000..6bea258 --- /dev/null +++ b/pets-fe/utils/tabbar.js @@ -0,0 +1,14 @@ +// tabBar 高亮同步。 +// +// 本来想让 custom-tab-bar 自己在 pageLifetimes.show 里算,页面一行都不用写。 +// 实测不行:自定义 tabBar 不在页面节点树里,pageLifetimes 拿不到可靠的时机, +// 结果是切到「我的」时高亮还留在「首页」。只能回到官方那套「页面 onShow 里推一把」。 +// +// 但索引仍然由 tabBar 按当前路由自己算,页面这边不写死 0/1/2/3/4—— +// 调 tab 顺序时改一个 LIST 就够了,五个页面一行都不用动。 +function syncTabBar(page) { + const bar = page.getTabBar && page.getTabBar(); + if (bar && bar.syncSelected) bar.syncSelected(); +} + +module.exports = { syncTabBar };