bugfix
This commit is contained in:
@@ -13,6 +13,8 @@ Component({
|
|||||||
data: {
|
data: {
|
||||||
selected: 0,
|
selected: 0,
|
||||||
unread: 0,
|
unread: 0,
|
||||||
|
// 弹层打开时页面调用 setHidden(true) 淡出,避免悬浮标签栏压在弹层之上
|
||||||
|
hidden: false,
|
||||||
list: [
|
list: [
|
||||||
{ pagePath: '/pages/wardrobe/wardrobe', text: '衣橱', icon: 'icon-hanger' },
|
{ pagePath: '/pages/wardrobe/wardrobe', text: '衣橱', icon: 'icon-hanger' },
|
||||||
{ pagePath: '/pages/outfit/outfit', text: '穿搭', icon: 'icon-shirt' },
|
{ pagePath: '/pages/outfit/outfit', text: '穿搭', icon: 'icon-shirt' },
|
||||||
@@ -75,6 +77,14 @@ Component({
|
|||||||
this.applyData({ selected: index })
|
this.applyData({ selected: index })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 弹层打开/关闭时淡出或恢复悬浮标签栏(供页面调用,内部保证首帧安全)
|
||||||
|
setHidden(hidden: boolean) {
|
||||||
|
const next = !!hidden
|
||||||
|
// 值未变化时不触发渲染:页面每次 onShow 都会校准一次,避免无谓的 setData
|
||||||
|
if (next === !!this.data.hidden) return
|
||||||
|
this.applyData({ hidden: next })
|
||||||
|
},
|
||||||
|
|
||||||
// 直接更新红点(供页面在已知数量时调用,不再触发二次请求)
|
// 直接更新红点(供页面在已知数量时调用,不再触发二次请求)
|
||||||
setUnread(n: number) {
|
setUnread(n: number) {
|
||||||
const unread = Number(n) || 0
|
const unread = Number(n) || 0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- v2 悬浮玻璃胶囊标签栏 -->
|
<!-- v2 悬浮玻璃胶囊标签栏(弹层打开时由页面调用 setHidden 淡出) -->
|
||||||
<view class="tabbar">
|
<view class="tabbar {{hidden ? 'is-hidden' : ''}}">
|
||||||
<view
|
<view
|
||||||
wx:for="{{list}}"
|
wx:for="{{list}}"
|
||||||
wx:key="pagePath"
|
wx:key="pagePath"
|
||||||
|
|||||||
@@ -14,6 +14,14 @@
|
|||||||
box-shadow: 0 0 0 1rpx rgba(0, 0, 0, .05), 0 20rpx 60rpx -20rpx rgba(0, 0, 0, .16);
|
box-shadow: 0 0 0 1rpx rgba(0, 0, 0, .05), 0 20rpx 60rpx -20rpx rgba(0, 0, 0, .16);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
transition: opacity .3s cubic-bezier(.32, .72, 0, 1), transform .3s cubic-bezier(.32, .72, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹层遮罩期间淡出:tabBar 由框架渲染在页面容器之上,页面内 z-index 盖不住它 */
|
||||||
|
.tabbar.is-hidden {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(calc(100% + 48rpx));
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"navigation-bar": "/components/navigation-bar/navigation-bar",
|
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||||
"v2-overlay": "/components/v2-overlay/index"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as auth from '../../utils/auth'
|
|||||||
import { UserInfo, QuotaItem } from '../../types/models'
|
import { UserInfo, QuotaItem } from '../../types/models'
|
||||||
import { QuotaType, STORAGE_KEYS } from '../../utils/config'
|
import { QuotaType, STORAGE_KEYS } from '../../utils/config'
|
||||||
import { formatDate } from '../../utils/format'
|
import { formatDate } from '../../utils/format'
|
||||||
import { setTabBarSelected, setTabBarUnread } from '../../utils/tabbar'
|
import { setTabBarSelected, setTabBarUnread, setTabBarHidden } from '../../utils/tabbar'
|
||||||
import { navScroll } from '../../utils/nav'
|
import { navScroll } from '../../utils/nav'
|
||||||
import { logger } from '../../utils/logger'
|
import { logger } from '../../utils/logger'
|
||||||
|
|
||||||
@@ -49,12 +49,6 @@ Page({
|
|||||||
quotaStats: [] as Array<{ key: number; label: string; remain: number; total: number }>,
|
quotaStats: [] as Array<{ key: number; label: string; remain: number; total: number }>,
|
||||||
// 滚动收缩:由 utils/nav.ts 的共享 handler 驱动
|
// 滚动收缩:由 utils/nav.ts 的共享 handler 驱动
|
||||||
navScrolled: false,
|
navScrolled: false,
|
||||||
// 性别选择:v2 玻璃动作表
|
|
||||||
sexVisible: false,
|
|
||||||
sexItems: [
|
|
||||||
{ text: '男', value: 1 },
|
|
||||||
{ text: '女', value: 2 },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// scroll-view 滚动 → 导航收缩为玻璃小标题
|
// scroll-view 滚动 → 导航收缩为玻璃小标题
|
||||||
@@ -74,6 +68,8 @@ Page({
|
|||||||
onShow() {
|
onShow() {
|
||||||
this.syncTabBar()
|
this.syncTabBar()
|
||||||
this.setToday()
|
this.setToday()
|
||||||
|
// 回到本页时按抽屉状态校准标签栏,防止切前后台/切 tab 后残留隐藏
|
||||||
|
setTabBarHidden(!!this.data.editVisible)
|
||||||
// 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求
|
// 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求
|
||||||
if (!auth.isLoggedIn()) {
|
if (!auth.isLoggedIn()) {
|
||||||
redirectToLogin()
|
redirectToLogin()
|
||||||
@@ -85,6 +81,11 @@ Page({
|
|||||||
this.fetchUnread()
|
this.fetchUnread()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 离开本页时恢复标签栏:此时抽屉不再可见,标签栏不能残留隐藏
|
||||||
|
onHide() {
|
||||||
|
setTabBarHidden(false)
|
||||||
|
},
|
||||||
|
|
||||||
// 拉取未读数:与 tabBar 红点同源(/notification/unread),保证两处数量一致
|
// 拉取未读数:与 tabBar 红点同源(/notification/unread),保证两处数量一致
|
||||||
fetchUnread() {
|
fetchUnread() {
|
||||||
request<{ unread_count: number }>({ url: '/notification/unread', showError: false, silentAuth: true })
|
request<{ unread_count: number }>({ url: '/notification/unread', showError: false, silentAuth: true })
|
||||||
@@ -148,6 +149,8 @@ Page({
|
|||||||
|
|
||||||
onEdit() {
|
onEdit() {
|
||||||
const u = this.data.userInfo
|
const u = this.data.userInfo
|
||||||
|
// 抽屉打开期间隐藏悬浮标签栏:tabBar 由框架渲染在页面之上,否则会压住抽屉底部按钮
|
||||||
|
setTabBarHidden(true)
|
||||||
this.setData({
|
this.setData({
|
||||||
editVisible: true,
|
editVisible: true,
|
||||||
avatarChanged: false,
|
avatarChanged: false,
|
||||||
@@ -163,6 +166,7 @@ Page({
|
|||||||
|
|
||||||
onCloseEdit() {
|
onCloseEdit() {
|
||||||
this.setData({ editVisible: false })
|
this.setData({ editVisible: false })
|
||||||
|
setTabBarHidden(false)
|
||||||
},
|
},
|
||||||
|
|
||||||
noop() {},
|
noop() {},
|
||||||
@@ -175,18 +179,11 @@ Page({
|
|||||||
this.setData({ 'editForm.username': e.detail.value })
|
this.setData({ 'editForm.username': e.detail.value })
|
||||||
},
|
},
|
||||||
|
|
||||||
onSexSelect() {
|
// 性别为两选一字段:抽屉内联胶囊直接选中,不再弹动作表(避免两层玻璃叠加)
|
||||||
this.setData({ sexVisible: true })
|
onSexTap(e: WechatMiniprogram.TouchEvent) {
|
||||||
},
|
const sex = Number((e.currentTarget.dataset as any).value) || 0
|
||||||
|
|
||||||
onSexPick(e: WechatMiniprogram.CustomEvent) {
|
|
||||||
const sex = Number(e.detail.value) || 0
|
|
||||||
logger.debug(LOG, '选择性别, sex=', sex)
|
logger.debug(LOG, '选择性别, sex=', sex)
|
||||||
this.setData({ 'editForm.sex': sex, sexVisible: false })
|
this.setData({ 'editForm.sex': sex })
|
||||||
},
|
|
||||||
|
|
||||||
onSexCancel() {
|
|
||||||
this.setData({ sexVisible: false })
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onBirthChange(e: WechatMiniprogram.CustomEvent) {
|
onBirthChange(e: WechatMiniprogram.CustomEvent) {
|
||||||
@@ -212,6 +209,8 @@ Page({
|
|||||||
saving: false,
|
saving: false,
|
||||||
avatarChanged: false,
|
avatarChanged: false,
|
||||||
})
|
})
|
||||||
|
// 抽屉关闭,恢复悬浮标签栏
|
||||||
|
setTabBarHidden(false)
|
||||||
this.fetchUser()
|
this.fetchUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +223,9 @@ Page({
|
|||||||
if (f.birth_day && f.birth_day !== u.birth_day) body.birth_day = f.birth_day
|
if (f.birth_day && f.birth_day !== u.birth_day) body.birth_day = f.birth_day
|
||||||
|
|
||||||
if (!Object.keys(body).length && !this.data.avatarChanged) {
|
if (!Object.keys(body).length && !this.data.avatarChanged) {
|
||||||
|
// 无变更直接关闭:同样要恢复标签栏,否则会残留隐藏
|
||||||
this.setData({ editVisible: false })
|
this.setData({ editVisible: false })
|
||||||
|
setTabBarHidden(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -137,11 +137,11 @@
|
|||||||
placeholder-class="input-ph"
|
placeholder-class="input-ph"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view class="form-field" bindtap="onSexSelect">
|
<view class="form-field">
|
||||||
<text class="form-label">性别</text>
|
<text class="form-label">性别</text>
|
||||||
<view class="form-value">
|
<view class="sex-pick">
|
||||||
<text class="{{editForm.sex ? '' : 'input-ph'}}">{{editForm.sex === 1 ? '男' : editForm.sex === 2 ? '女' : '请选择'}}</text>
|
<view class="sex-pill {{editForm.sex === 1 ? 'is-on' : ''}}" data-value="1" bindtap="onSexTap">男</view>
|
||||||
<view class="icon icon-chevron-right form-arrow"></view>
|
<view class="sex-pill {{editForm.sex === 2 ? 'is-on' : ''}}" data-value="2" bindtap="onSexTap">女</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="form-field">
|
<view class="form-field">
|
||||||
@@ -164,12 +164,4 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 性别选择:底部动作表 -->
|
|
||||||
<v2-overlay
|
|
||||||
visible="{{sexVisible}}"
|
|
||||||
type="actionsheet"
|
|
||||||
items="{{sexItems}}"
|
|
||||||
bind:select="onSexPick"
|
|
||||||
bind:cancel="onSexCancel"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -220,3 +220,27 @@
|
|||||||
height: 26rpx;
|
height: 26rpx;
|
||||||
color: var(--ink-4);
|
color: var(--ink-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 性别:行内两选一胶囊(选中实心黑,零彩色) */
|
||||||
|
.sex-pick {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sex-pill {
|
||||||
|
height: 60rpx;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
border-radius: var(--r-pill);
|
||||||
|
background: var(--fill);
|
||||||
|
color: var(--ink-2);
|
||||||
|
font-size: 26rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
transition: background .18s var(--ease), color .18s var(--ease);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sex-pill.is-on {
|
||||||
|
background: var(--ink);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,3 +31,13 @@ export function setTabBarSelected(index: number): void {
|
|||||||
if (typeof tabBar.setSelected === 'function') tabBar.setSelected(index)
|
if (typeof tabBar.setSelected === 'function') tabBar.setSelected(index)
|
||||||
else tabBar.setData({ selected: index })
|
else tabBar.setData({ selected: index })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 弹层遮罩期间隐藏悬浮标签栏:tabBar 由框架渲染在页面容器之上,
|
||||||
|
// 页面内任何 z-index 都盖不住它,只能让组件自身淡出(内部同样走首帧安全更新)。
|
||||||
|
// 弹层关闭后必须恢复,页面 onShow 时可再校准一次,避免残留隐藏。
|
||||||
|
export function setTabBarHidden(hidden: boolean): void {
|
||||||
|
const tabBar = getTabBarInstance()
|
||||||
|
if (!tabBar) return
|
||||||
|
if (typeof tabBar.setHidden === 'function') tabBar.setHidden(hidden)
|
||||||
|
else tabBar.setData({ hidden })
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user