feat: 完成首页修改

This commit is contained in:
R524809
2026-04-30 18:02:11 +08:00
parent 44182d011d
commit 50394154f7
3 changed files with 89 additions and 54 deletions
+27 -12
View File
@@ -45,29 +45,44 @@
} }
.home-tabs-wrap { .home-tabs-wrap {
margin-top: @section-gap; margin-top: 48rpx;
} }
.home-hero-placeholder { .home-hero-placeholder {
margin: @section-gap @page-padding-x 0; margin: @section-gap @page-padding-x 0;
height: 480rpx; height: 450rpx;
border-radius: 40rpx; border-radius: 40rpx;
background: rgba(50, 46, 37, 0.04); background: rgba(50, 46, 37, 0.04);
} }
/** 首页顶部「精选」横滑行(与下方模块 track 列表的 .home-track-row 区分) */ /** 首页顶部「精选」swiper 轮播 */
.home-hero-row { .home-hero-swiper {
display: inline-flex; margin-top: 16rpx;
flex-direction: row; width: 100%;
gap: @section-gap-sm; height: 450rpx;
padding: 24rpx @page-padding-x; }
.home-hero-swiper-item {
box-sizing: border-box;
}
.home-hero-card-wrap {
padding: 24rpx;
box-sizing: border-box;
transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94),
opacity 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transform: scale(0.9);
opacity: 0.5;
}
.home-hero-card-wrap--active {
transform: scale(1);
opacity: 1;
} }
.home-hero-card { .home-hero-card {
width: 560rpx; width: 100%;
flex-shrink: 0;
border-radius: 32rpx; border-radius: 32rpx;
/* 让阴影不被自身 overflow: hidden 裁切 */
overflow: visible; overflow: visible;
background: #ffffff; background: #ffffff;
box-shadow: 0 10rpx 28rpx rgba(50, 46, 37, 0.08); box-shadow: 0 10rpx 28rpx rgba(50, 46, 37, 0.08);
@@ -118,7 +133,7 @@
.home-hero-card__title-row { .home-hero-card__title-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: baseline; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 16rpx; gap: 16rpx;
/* 允许 flex 子项在文本过长时正确截断 */ /* 允许 flex 子项在文本过长时正确截断 */
+5
View File
@@ -145,6 +145,7 @@ Page({
activeTab: 'all', activeTab: 'all',
ageBands: [] as HomeAgeBandView[], ageBands: [] as HomeAgeBandView[],
activeAgeBand: '3-4' as AgeBandKey, activeAgeBand: '3-4' as AgeBandKey,
heroSwiperCurrent: 0,
featuredItems: SKELETON_FEATURED, featuredItems: SKELETON_FEATURED,
hotRecommends: SKELETON_HOT, hotRecommends: SKELETON_HOT,
sections: [] as HomeDisplaySectionView[], sections: [] as HomeDisplaySectionView[],
@@ -197,6 +198,10 @@ Page({
// ── Tab & Navigation ── // ── Tab & Navigation ──
onHeroSwiperChange(e: WechatMiniprogram.SwiperChange) {
this.setData({ heroSwiperCurrent: e.detail.current });
},
onTabChange(e: WechatMiniprogram.CustomEvent) { onTabChange(e: WechatMiniprogram.CustomEvent) {
const id = e.detail.id as string | undefined; const id = e.detail.id as string | undefined;
if (!id) return; if (!id) return;
+57 -42
View File
@@ -2,7 +2,7 @@
<nav-bar title="" /> <nav-bar title="" />
<view class="home-body"> <view class="home-body">
<view class="home-search-wrap"> <!-- <view class="home-search-wrap">
<view class="home-search"> <view class="home-search">
<van-icon <van-icon
name="search" name="search"
@@ -13,7 +13,7 @@
>{{searchPlaceholder}}</text >{{searchPlaceholder}}</text
> >
</view> </view>
</view> </view> -->
<view class="home-tabs-wrap"> <view class="home-tabs-wrap">
<category-tabs <category-tabs
@@ -22,50 +22,63 @@
bind:change="onTabChange" /> bind:change="onTabChange" />
</view> </view>
<scroll-view class="home-track-scroll" scroll-x enable-flex> <swiper
<view class="home-hero-row"> class="home-hero-swiper"
previous-margin="100rpx"
next-margin="100rpx"
circular="{{featuredItems.length > 1 && !loading}}"
autoplay="{{!loading}}"
interval="{{4000}}"
duration="{{600}}"
easing-function="easeInOutCubic"
bindchange="onHeroSwiperChange">
<swiper-item
wx:for="{{featuredItems}}"
wx:key="id"
class="home-hero-swiper-item">
<view <view
wx:for="{{featuredItems}}" class="home-hero-card-wrap {{heroSwiperCurrent === index ? 'home-hero-card-wrap--active' : ''}}">
wx:key="id" <view
class="home-hero-card {{item.skeleton ? 'home-hero-card--skeleton' : ''}}" class="home-hero-card {{item.skeleton ? 'home-hero-card--skeleton' : ''}}"
data-title="{{item.title}}" data-title="{{item.title}}"
data-path="{{item.path}}" data-path="{{item.path}}"
bindtap="{{item.skeleton ? '' : 'onTapFeatured'}}"> bindtap="{{item.skeleton ? '' : 'onTapFeatured'}}">
<view class="home-hero-card__top"> <view class="home-hero-card__top">
<image <image
wx:if="{{!item.skeleton && item.previewImg}}" wx:if="{{!item.skeleton && item.previewImg}}"
class="home-hero-card__cover" class="home-hero-card__cover"
src="{{item.previewImg}}" src="{{item.previewImg}}"
mode="aspectFill" /> mode="aspectFill" />
<text <text
wx:if="{{!item.skeleton && !item.previewImg}}" wx:if="{{!item.skeleton && !item.previewImg}}"
class="home-hero-card__icon" class="home-hero-card__icon"
>{{item.icon}}</text >{{item.icon}}</text
>
<text
wx:if="{{item.badge}}"
class="home-hero-card__badge"
>{{item.badge}}</text
>
</view>
<view class="home-hero-card__body">
<view class="home-hero-card__title-row">
<text class="home-hero-card__title"
>{{item.title}}</text
> >
<text <text
wx:if="{{!item.skeleton}}" wx:if="{{item.badge}}"
class="home-hero-card__meta" class="home-hero-card__badge"
>{{item.ageBand}} · {{item.difficulty}}</text >{{item.badge}}</text
>
</view>
<view class="home-hero-card__body">
<view class="home-hero-card__title-row">
<text class="home-hero-card__title"
>{{item.title}}</text
>
<text
wx:if="{{!item.skeleton}}"
class="home-hero-card__meta"
>{{item.ageBand}}·{{item.difficulty}}</text
>
</view>
<text class="home-hero-card__sub"
>{{item.subtitle}}</text
> >
</view> </view>
<text class="home-hero-card__sub"
>{{item.subtitle}}</text
>
</view> </view>
</view> </view>
</view> </swiper-item>
</scroll-view> </swiper>
<view class="home-section-panel"> <view class="home-section-panel">
<view class="home-section-head"> <view class="home-section-head">
@@ -141,9 +154,11 @@
</view> </view>
<view <view
wx:if="{{!item.skeleton}}" wx:if="{{!item.skeleton}}"
class="home-hot-card__action" class="home-hot-card__action">
> <toy-icon
<toy-icon name="arrow-right" size="36rpx" color="#2b2b2b" /> name="arrow-right"
size="36rpx"
color="#2b2b2b" />
</view> </view>
</view> </view>
</view> </view>