feat(index): 实现热销商品Tabs粘性布局功能
- 引入Sticky组件实现Tabs吸顶效果 - 添加粘性状态变化回调通知父组件- 动态计算系统状态栏高度作为吸顶阈值-优化Tabs样式在粘性状态下的视觉表现 - 调整商品列表间距以适配新布局- 完善首页Header组件与Tabs粘性状态联动逻辑 - 移除useDidHide中的主题设置调用 - 初始化时设置应用主题配置
This commit is contained in:
@@ -38,6 +38,8 @@ function App(props: { children: any; }) {
|
|||||||
};
|
};
|
||||||
// 可以使用所有的 React Hooks
|
// 可以使用所有的 React Hooks
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// 设置主题
|
||||||
|
handleTheme()
|
||||||
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
||||||
Taro.getSetting({
|
Taro.getSetting({
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
@@ -102,7 +104,6 @@ function App(props: { children: any; }) {
|
|||||||
|
|
||||||
// 对应 onHide
|
// 对应 onHide
|
||||||
useDidHide(() => {
|
useDidHide(() => {
|
||||||
handleTheme()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return props.children
|
return props.children
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {Image, Tabs, Empty} from '@nutui/nutui-react-taro'
|
import {Image, Tabs, Empty, Sticky} from '@nutui/nutui-react-taro'
|
||||||
import {Share} from '@nutui/icons-react-taro'
|
import {Share} from '@nutui/icons-react-taro'
|
||||||
import {View, Text} from '@tarojs/components';
|
import {View, Text} from '@tarojs/components';
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||||
import {pageShopGoods} from "@/api/shop/shopGoods";
|
import {pageShopGoods} from "@/api/shop/shopGoods";
|
||||||
|
|
||||||
const BestSellers = () => {
|
const BestSellers = (props: {onStickyChange?: (isSticky: boolean) => void}) => {
|
||||||
const [tab1value, setTab1value] = useState<string | number>('0')
|
const [tab1value, setTab1value] = useState<string | number>('0')
|
||||||
const [list, setList] = useState<ShopGoods[]>([])
|
const [list, setList] = useState<ShopGoods[]>([])
|
||||||
const [goods, setGoods] = useState<ShopGoods>()
|
const [goods, setGoods] = useState<ShopGoods>()
|
||||||
|
const [stickyStatus, setStickyStatus] = useState<boolean>(false)
|
||||||
|
|
||||||
const reload = () => {
|
const reload = () => {
|
||||||
pageShopGoods({}).then(res => {
|
pageShopGoods({}).then(res => {
|
||||||
@@ -48,37 +49,62 @@ const BestSellers = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理粘性布局状态变化
|
||||||
|
const onStickyChange = (isSticky: boolean) => {
|
||||||
|
setStickyStatus(isSticky)
|
||||||
|
// 通知父组件粘性状态变化
|
||||||
|
props.onStickyChange?.(isSticky)
|
||||||
|
console.log('Tabs 粘性状态:', isSticky ? '已固定' : '取消固定')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取小程序系统信息
|
||||||
|
const getSystemInfo = () => {
|
||||||
|
const systemInfo = Taro.getSystemInfoSync()
|
||||||
|
// 状态栏高度 + 导航栏高度 (一般为44px)
|
||||||
|
return (systemInfo.statusBarHeight || 0) + 44
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reload()
|
reload()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// 注意:不在这里配置分享,避免与首页分享冲突
|
|
||||||
// 商品分享应该在商品详情页处理,首页分享应该分享首页本身
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View className={'py-3'}>
|
<View className={'py-3'}>
|
||||||
{/* Tabs切换组件 */}
|
{/* Tabs粘性布局组件 */}
|
||||||
<Tabs
|
<Sticky
|
||||||
value={tab1value}
|
threshold={getSystemInfo()}
|
||||||
className={'w-full mb-4'}
|
onChange={onStickyChange}
|
||||||
onChange={(value) => {
|
|
||||||
setTab1value(value)
|
|
||||||
}}
|
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: 'transparent',
|
zIndex: 999,
|
||||||
|
backgroundColor: stickyStatus ? '#ffffff' : 'transparent',
|
||||||
|
boxShadow: stickyStatus ? '0 2px 8px rgba(0,0,0,0.1)' : 'none',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
}}
|
}}
|
||||||
activeType="smile"
|
|
||||||
>
|
>
|
||||||
<Tabs.TabPane title="今日主推">
|
<Tabs
|
||||||
</Tabs.TabPane>
|
value={tab1value}
|
||||||
<Tabs.TabPane title="即将到期">
|
className={'w-full'}
|
||||||
</Tabs.TabPane>
|
onChange={(value) => {
|
||||||
<Tabs.TabPane title="活动预告">
|
setTab1value(value)
|
||||||
</Tabs.TabPane>
|
}}
|
||||||
</Tabs>
|
style={{
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
paddingTop: stickyStatus ? '8px' : '0',
|
||||||
|
paddingBottom: stickyStatus ? '8px' : '0',
|
||||||
|
}}
|
||||||
|
activeType="smile"
|
||||||
|
>
|
||||||
|
<Tabs.TabPane title="今日主推">
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane title="即将到期">
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane title="活动预告">
|
||||||
|
</Tabs.TabPane>
|
||||||
|
</Tabs>
|
||||||
|
</Sticky>
|
||||||
|
|
||||||
<View className={'flex flex-col justify-between items-center rounded-lg px-2'}>
|
<View className={'flex flex-col justify-between items-center rounded-lg px-2 mt-4'}>
|
||||||
{/* 今日主推 */}
|
{/* 今日主推 */}
|
||||||
{tab1value == '0' && list?.map((item, index) => {
|
{tab1value == '0' && list?.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import './index.scss'
|
|||||||
function Home() {
|
function Home() {
|
||||||
// 吸顶状态
|
// 吸顶状态
|
||||||
const [stickyStatus, setStickyStatus] = useState<boolean>(false)
|
const [stickyStatus, setStickyStatus] = useState<boolean>(false)
|
||||||
|
// Tabs粘性状态
|
||||||
|
const [tabsStickyStatus, setTabsStickyStatus] = useState<boolean>(false)
|
||||||
|
|
||||||
useShareAppMessage(() => {
|
useShareAppMessage(() => {
|
||||||
// 获取当前用户ID,用于生成邀请链接
|
// 获取当前用户ID,用于生成邀请链接
|
||||||
@@ -85,6 +87,11 @@ function Home() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理Tabs粘性状态变化
|
||||||
|
const handleTabsStickyChange = (isSticky: boolean) => {
|
||||||
|
setTabsStickyStatus(isSticky)
|
||||||
|
}
|
||||||
|
|
||||||
const reload = () => {
|
const reload = () => {
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -150,13 +157,19 @@ function Home() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Sticky threshold={0} onChange={() => onSticky(arguments)}>
|
{/* Header区域 - 根据Tabs粘性状态决定是否固定 */}
|
||||||
<Header stickyStatus={stickyStatus}/>
|
{tabsStickyStatus ? (
|
||||||
</Sticky>
|
<Sticky threshold={0}>
|
||||||
|
<Header stickyStatus={tabsStickyStatus}/>
|
||||||
|
</Sticky>
|
||||||
|
) : (
|
||||||
|
<Header stickyStatus={tabsStickyStatus}/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className={'flex flex-col mt-12'}>
|
<div className={'flex flex-col mt-12'}>
|
||||||
<Menu/>
|
<Menu/>
|
||||||
<Banner/>
|
<Banner/>
|
||||||
<BestSellers/>
|
<BestSellers onStickyChange={handleTabsStickyChange}/>
|
||||||
{/*<GoodsList/>*/}
|
{/*<GoodsList/>*/}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user