如图:
思路
wxml包含两部分,一部分是列表渲染tabs的每一项,另一部分用来展示滑块,根据当前选中的index,来计算滑块的位置,用css的transition属性做动画过渡
wxml
<view class="tabs">
<block wx:for="{{tabs}}" wx:key="key">
<view class="item {{index === active ? 'active' : ''}}" data-active="{{index}}" bindtap="onActiveChange">{{item.title}}</view>
</block>
<view class="bg" style="left: calc({{tabItemWidth}} * {{active}});width: {{tabItemWidth}};"></view>
</view>
less
.tabs {
margin: 10rpx 30rpx;
display: flex;
align-items: center;
border-radius: 10rpx;
background-color: #f7f7f7;
position: relative;
.item {
position: relative;
z-index: 20;
flex: 1;
text-align: center;
padding: 20rpx;
border-radius: 10rpx;
transition: all 0.3s;
&.active {
color: white;
}
}
.bg {
position: absolute;
top: 0;
background-color: green;
height: 100%;
border-radius: 10rpx;
z-index: 10;
transition: all 0.3s;
}
}
js(关键代码)
data: {
// 渲染tab的列表
tabs: [
{
title: "tab1",
key: "tab1",
},
{
title: "tab2",
key: "tab2",
},
{
title: "tab3",
key: "tab3",
},
],
// 当前活动的tab
active: 0,
// 每一项tab的宽度
tabItemWidth: "",
},
/** 监听切换 */
onActiveChange(e: WechatMiniprogram.CustomEvent) {
this.setData({
active: e.currentTarget.dataset.active,
// 这里设置滑块的位置
tabItemWidth: (1 / this.data.tabs.length) * 100 + "%",
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
// 加载完成后设置一次滑块的位置
this.setData({
tabItemWidth: (1 / this.data.tabs.length) * 100 + "%",
});
},