fix: 顶栏颜色跟随小程序主题并保留跟随系统

This commit is contained in:
2026-08-06 19:54:05 +08:00
parent 9716148f15
commit f4f54a8720
84 changed files with 484 additions and 124 deletions
+17 -13
View File
@@ -3,14 +3,16 @@
bottom: 0;
left: 0;
right: 0;
height: 120px;
background: rgba(255, 255, 255, 0.75);
height: calc(96px + constant(safe-area-inset-bottom));
height: calc(96px + env(safe-area-inset-bottom));
box-sizing: border-box;
background: rgba(255, 255, 255, 0.78);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
display: flex;
justify-content: space-around;
align-items: center;
box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.08);
box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.08);
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
z-index: 1000;
@@ -18,10 +20,10 @@
/* 自定义组件样式隔离:两套主题配色在组件内自包含,不依赖全局 app.wxss */
.custom-tab-bar.theme-dark {
background: rgba(25, 25, 25, 0.75);
background: rgba(25, 25, 25, 0.78);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.5);
box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.45);
}
.tab-item {
@@ -29,28 +31,31 @@
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px 20px;
padding: 0 12px;
position: relative;
flex: 1;
max-width: 160px;
}
.tab-icon-img {
width: 28px;
height: 28px;
margin-bottom: 4px;
width: 40px;
height: 40px;
margin-bottom: 2px;
transition: transform 0.2s;
opacity: 0.6;
opacity: 0.8;
}
.tab-item.active .tab-icon-img {
transform: scale(1.15);
transform: scale(1.08);
opacity: 1;
}
.tab-label {
font-size: 20px;
color: #b08d8d;
font-weight: 600;
font-weight: 700;
transition: color 0.2s;
line-height: 22px;
}
.custom-tab-bar.theme-dark .tab-label {
@@ -59,7 +64,6 @@
.tab-item.active .tab-label {
color: #ff9a9e;
font-weight: 700;
}
.custom-tab-bar.theme-dark .tab-item.active .tab-label {
+33 -10
View File
@@ -7,18 +7,28 @@ import { applyPageBackground } from '../utils/themeBackground'
import './index.scss'
const TABS = [
{ pagePath: '/pages/index/index', text: '首页', icon: '/icon/首页.svg', iconActive: '/icon/首页-fill.svg' },
{ pagePath: '/pages/shop/index', text: '商品', icon: '/icon/商品.svg', iconActive: '/icon/商品-fill.svg' },
{ pagePath: '/pages/designList/index', text: '设计清单', icon: '/icon/调色盘.svg', iconActive: '/icon/调色盘-fill.svg' },
{ pagePath: '/pages/orders/index', text: '订单', icon: '/icon/包裹.svg', iconActive: '/icon/包裹-fill.svg' },
{ pagePath: '/pages/profile/index', text: '我的', icon: '/icon/个人.svg', iconActive: '/icon/个人-fill.svg' }
{ pagePath: '/pages/index/index', label: '首页', icon: '/icon/首页.svg', iconActive: '/icon/首页-fill.svg' },
{ pagePath: '/pages/shop/index', label: '商品', icon: '/icon/商品.svg', iconActive: '/icon/商品-fill.svg' },
{ pagePath: '/pages/designList/index', label: '设计清单', icon: '/icon/调色盘.svg', iconActive: '/icon/调色盘-fill.svg' },
{ pagePath: '/pages/orders/index', label: '订单', icon: '/icon/包裹.svg', iconActive: '/icon/包裹-fill.svg' },
{ pagePath: '/pages/profile/index', label: '我的', icon: '/icon/个人.svg', iconActive: '/icon/个人-fill.svg' }
]
function matchTab(path: string): string {
const idx = TABS.findIndex((t) => path.endsWith(t.pagePath))
return TABS[idx >= 0 ? idx : 0].pagePath
}
function currentTabPath(): string {
const path = Taro.getCurrentInstance().router?.path || 'pages/index/index'
return matchTab(path)
}
export default function CustomTabBar() {
// 自定义 tabBar 是独立组件,无法继承页面里的 React Context
// 初始值从本地主题配置读取,之后通过 eventCenter 跟随主题切换
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(resolveTheme(getTheme()))
const currentPath = `/${Taro.getCurrentInstance().router?.path || 'pages/index/index'}`
// 微信自定义 tabBar 不会自动感知 page 路由变化,用 state 保持选中态响应式
const [activeTab, setActiveTab] = useState<string>(currentTabPath)
useEffect(() => {
const handler = (t: 'light' | 'dark') => setResolvedTheme(t)
@@ -28,6 +38,17 @@ export default function CustomTabBar() {
}
}, [])
// 其它入口(如页面内部调用 switchTab)也会回到 tabBar,收到事件后重新同步选中态
useEffect(() => {
const handler = (path?: string) => {
setActiveTab(matchTab(path || Taro.getCurrentInstance().router?.path || 'pages/index/index'))
}
Taro.eventCenter.on('tabBarChange', handler)
return () => {
Taro.eventCenter.off('tabBarChange', handler)
}
}, [])
// tabBar 是 tab 页切换时必定会挂载/更新的组件:在这里也刷新一次页面背景,
// 兜底处理“登录后切到受保护页面”时自定义导航区背景,避免残留白色
useEffect(() => {
@@ -35,13 +56,15 @@ export default function CustomTabBar() {
}, [resolvedTheme])
const switchTab = (url: string) => {
setActiveTab(matchTab(url))
Taro.switchTab({ url })
Taro.eventCenter?.trigger('tabBarChange', url)
}
return (
<View className={`custom-tab-bar theme-${resolvedTheme}`}>
{TABS.map((tab) => {
const isActive = currentPath === tab.pagePath
const isActive = tab.pagePath === activeTab
return (
<View
key={tab.pagePath}
@@ -49,7 +72,7 @@ export default function CustomTabBar() {
onTap={() => switchTab(tab.pagePath)}
>
<Image className={`tab-icon-img ${isActive ? 'active' : ''}`} src={isActive ? tab.iconActive : tab.icon} mode='aspectFit' />
<Text className='tab-label'>{tab.text}</Text>
<Text className='tab-label'>{tab.label}</Text>
</View>
)
})}