Structure WXML
L'interface utilise un composant scroll-view pour les titres d'ongelts permettant le défilement horizontal, et un composant swiper pour le contenu à glissement latéral. Les données sont générées dynamiquement via des boucles wx:for.
Points clés :
- L'attribut
data-indexcapture l'index de l'onglet cliqué via l'événementswitchNav - La propriété
currentdu swiper contrôle l'onglet affiché - L'événement
changedu swiper déclenchechangeTabpour mettre à jour l'état
<view>
<scroll-view scroll-x="true" class="nav-container" scroll-left="{{scrollPosition}}">
<view wx:for="{{tabs}}" wx:key="index" class="nav-item {{activeIndex==index?'selected':''}}"
data-index="{{index}}" bindtap="switchNav">{{item}}</view>
</scroll-view>
<swiper class="content-area" current="{{activeIndex}}" duration="300" bindchange="changeTab"
style="height:{{computedHeight}}rpx">
<swiper-item wx:for="{{tabs}}" wx:key="index">
<scroll-view scroll-y="true" class="scroll-container">
<view wx:for="{{sampleData}}" wx:key="*this" class="card-item">
<view class="user-avatar">
<image class="avatar-img" src="/images/avatar.png"></image>
</view>
<view class="user-details">
<view class="user-name">ExpertName</view>
<view class="user-title">Spécialiste reconnu</view>
<view class="user-stats">150 réponses, 2500 consultations</view>
</view>
<navigator url="/pages/consult/consultDetail" class="consult-btn">Consulter</navigator>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
Logique JavaScript
Page({
data: {
computedHeight: "",
activeIndex: 0,
scrollPosition: 0,
tabs: ["Santé", "Relations", "Carrière", "Parentalité", "Juridique", "Jeunesse", "Tous", "Divers"],
sampleData: Array(8).fill(null)
},
changeTab: function(e) {
const newIndex = e.detail.current;
this.setData({ activeIndex: newIndex });
this.adjustScroll();
},
switchNav: function(e) {
const clickedIndex = parseInt(e.currentTarget.dataset.index);
if (this.data.activeIndex !== clickedIndex) {
this.setData({ activeIndex: clickedIndex });
}
},
adjustScroll: function() {
const threshold = 4;
const scrollValue = this.data.activeIndex > threshold ? 300 : 0;
this.setData({ scrollPosition: scrollValue });
},
onLoad: function() {
const system = wx.getSystemInfoSync();
const heightCalc = (system.windowHeight * (750 / system.windowWidth)) - 180;
this.setData({ computedHeight: heightCalc });
}
});
Styles WXSS
.nav-container {
height: 80rpx; width: 100%;
background: #F7F7F7;
position: fixed; top: 0;
white-space: nowrap;
}
.nav-item {
margin: 0 36rpx;
display: inline-block;
}
.nav-item.selected {
color: #4675F9;
position: relative;
}
.nav-item.selected:after {
content: "";
height: 8rpx;
width: 52rpx;
background: #4675F9;
position: absolute;
bottom: 0;
left: 5rpx;
border-radius: 16rpx;
}
.card-item {
display: flex;
padding: 30rpx;
align-items: center;
border-bottom: 1px solid #F2F2F2;
}
.user-avatar {
width: 100rpx;
height: 100rpx;
margin-right: 30rpx;
}
.user-details {
flex-grow: 2;
color: #B0B0B0;
line-height: 1.5em;
}
.user-name {
font-size: 16px;
color: #000;
margin-bottom: 6px;
}
.consult-btn {
width: 120rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border: 1px solid #4675F9;
color: #4675F9;
border-radius: 60rpx;
}
.content-area {
margin-top: 80rpx;
}
.scroll-container {
height: 100%;
}