小程序tab栏筛选功能 ---底部弹出动画

  • 仿今日头条app的tab栏功能
  • 在这里插入图片描述
  • 这里讲tab栏还有弹出功能封装了组件
  • 组件的html
<scroll-view class="tab-item" scroll-x scroll-with-animation="true" bindscrolltoupper="toUpper" bindscrolltolower="toLower" id="scroll-view" scroll-left="{{ scrollLeft }}">
    <view class="tab-item-sty">
        <view wx:for="{{typeList}}" wx:key="{{index}}" wx:for-index="index" bindtap="onButtonChange" data-type="{{item.type}}" id="item-{{ item.type }}" data-categoryId="{{item.categoryId}}" class="view-item {{item.select ? 'font-w' : 'font-b'}}">
            {{item.name}}
        </view>
    </view>
</scroll-view>
<view class="detail" bind:tap="showModal">
    <image src="../../images/pop.png" class="image-pop" />
</view>
<view class="modals modals-bottom-dialog" hidden="{{hideModal}}">
    <!-- <view class="modals-cancel" bindtap="hideModal"></view> -->
    <view class="bottom-dialog-body bottom-pos" animation="{{animationData}}">
        <view class="pop-box">
            <view class="title">
                全部分类
                <image src="../../images/close.png" class="close" bind:tap="hideModal" />
            </view>
            <view class="list">
                <view class="list-item {{item.select ? 'select-item' : ''}}" wx:for="{{typeList}}" wx:if="{{item.name.length!==0}}" wx:key="{{index}}" bind:tap="onButtonChange" data-type="{{item.type}}">{{item.name}}</view>
            </view>
        </view>
    </view>
</view>

  • 组件的js
Component({
  properties: {
    typeList: {
      type: Array,
      value: []
    }
  },
  data: {
    hideModal: true, //模态框的状态  true-隐藏  false-显示
    scrollLeft: 0,
  },
  methods: {
    onButtonChange: function (e) {
      const list = this.data.typeList
      let that = this;
      list.forEach(item => {
        if (item.type === e.currentTarget.dataset.type) {
          item.select = true
        } else {
          item.select = false
        }
      })
      that.setData({
        typeList: list,
      })
      this.hideModal()
      var query = wx.createSelectorQuery().in(that);//创建节点查询器
      query.select('#item-' + e.currentTarget.dataset.type).boundingClientRect();//选择id='#item-' + selectedId的节点,获取节点位置信息的查询请求
      query.select('#scroll-view').boundingClientRect();//获取滑块的位置信息
      query.select('#scroll-view').scrollOffset();//获取页面滑动位置的查询请求
      query.exec(function (res) {
        that.setData({
          scrollLeft: res[2].scrollLeft + res[0].left + res[0].width / 2 - res[1].width / 2
        });
      });
      this.triggerEvent('chooseType', e.currentTarget.dataset)
    },
    // 显示遮罩层 
    showModal() {
      this.setData({
        hideModal: false
      })
      var animation = wx.createAnimation({
        duration: 600, //动画的持续时间 默认400ms 数值越大,动画越慢 数值越小,动画越快 
        timingFunction: 'ease',//动画以低速开始,然后加快,在结束前变慢 //动画的效果 默认值是linear 
      })
      this.animation = animation
      setTimeout(() => {
        this.fadeIn(); //调用显示动画 
      }, 200)
    },
    // 隐藏遮罩层 
    hideModal() {
      var animation = wx.createAnimation({
        duration: 600, //动画的持续时间 默认400ms 数值越大,动画越慢 数值越小,动画越快 
        timingFunction: 'ease', //动画的效果 默认值是linear 
      })
      this.animation = animation
      this.fadeDown(); //调用隐藏动画 
      setTimeout(() => {
        this.setData({
          hideModal: true
        })
      }, 720) //先执行下滑动画,再隐藏模块 
    },
    //动画集 
    fadeIn() {
      this.animation.translateY(0).step()
      this.setData({
        animationData: this.animation.export() //动画实例的export方法导出动画数据传递给组件的animation属性 
      })
    },
    fadeDown() {
      this.animation.translateY(800).step()
      this.setData({
        animationData: this.animation.export(),
      })
    }
  }
})

  • 组件的css样式
/* 切换 */

.tab-item {
  width: calc(100% - 18rpx);
  height: 80rpx;
  line-height: 80rpx;
  background: #fff;
}

.tab-item-sty {
  display: flex;
  align-items: center;
}

.tab-item-sty .view-item {
  position: relative;
  display: inline-block;
  margin: 0 10rpx 0 0;
  flex-shrink: 0;
  width: auto !important;
  height: 52rpx;
  min-height: 52rpx !important;
  line-height: 52rpx;
  padding: 0 20rpx;
  border: none;
}

/* 点击后的效果 */
.tab-item-sty .font-w {
  font-size: 36rpx;
  font-weight: Bold;
  color: #DB1100;
}

.tab-item-sty .font-w::before {
  content: "";
  width: 42rpx;
  height: 6rpx;
  background-color: #DC1000;
  border-radius: 3rpx;
  position: absolute;
  left: 50%;
  bottom: -42%;
  transform: translate(-50%, 100%);
}

.tab-item-sty .font-b {
  font-size: 32rpx;
  color: #343434;
}

/* 隐藏滚动条 */
::-webkit-scrollbar {
  width: 0;
  height: 0;
  color: transparent;
}

.detail {
  width: 100rpx;
  height: 80rpx;
  background: #fff;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 3;
  text-align: center;
  line-height: 80rpx;
}

.image-pop {
  width: 30rpx;
  height: 30rpx;
}

/* 弹框 */
/*模态框*/
.modals-cancel {
  position: absolute;
  z-index: 1000;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
}
.bottom-dialog-body {
  position: fixed;
  z-index: 10001;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  background-color: #fff;
  box-sizing: border-box;
  padding: 57rpx 20rpx 0 20rpx;
}
 
/*动画前初始位置*/
.bottom-pos {
  -webkit-transform: translateY(100%);
  transform: translateY(100%);
}

.title {
  color: #242424;
  font-size: 28rpx;
  font-weight: bold;
}
.close{
  width: 40rpx;
  height: 40rpx;
  float: right;
  font-size: 28rpx;
}
.list {
  width: 100%;
  display: flex;
  flex-wrap:wrap;
  justify-content:space-between;
  margin-top: 60rpx;
}

.list-item {
  width: 223rpx;
  height: 76rpx;
  line-height: 76rpx;
  background: #F8F8F8;
  border-radius: 38rpx;
  text-align: center;
  color: #333333;
  font-size: 30rpx;
  margin-bottom:40rpx;
}
.select-item{
  color: #C50000;
  font-size: 30rpx;
  border: 1rpx solid #C50000;
  background: #fff;
}




 

 
 
  • 父组件
  • json:注册组件,位置写你本地的位置
  "usingComponents": {
    "tab-scroll":"../../components/tabScroll/tabScroll",

  },
  • 父组件的html
<view class="box">
    <tab-scroll typeList="{{typeList}}" bind:chooseType="chooseType"></tab-scroll>

</view>
  • 父组件的css
page {
    width: 100%;
    height: auto;
    overflow-y: auto;
    background: #f7f7f7;
  }
  .box{
      box-sizing: border-box;
      width: 100%;
  }
  • 父组件的js
Page({
  data: {
   
    typeList: [
      { type: 'all', name: '全部', select: true,categoryId:'' },
       { type: '1', name: '全部1111', select: false,categoryId:'' },
    ],

  },
  onLoad: function (options) {


  },

  chooseType: function (e) {
    console.log(e.detail)
//子组件触发的父组件的方法
 
  },

})

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值