小程序点击tab的滑动样式

488 阅读1分钟

如图:

动画.gif

思路

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 + "%",
    });
  },