- 仿今日头条app的tab栏功能
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/efeb0c18fdd1d1242fdade7140ce2472.gif#pic_center)
- 这里讲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>
Component({
properties: {
typeList: {
type: Array,
value: []
}
},
data: {
hideModal: true,
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();
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,
timingFunction: 'ease',
})
this.animation = animation
setTimeout(() => {
this.fadeIn();
}, 200)
},
hideModal() {
var animation = wx.createAnimation({
duration: 600,
timingFunction: 'ease',
})
this.animation = animation
this.fadeDown();
setTimeout(() => {
this.setData({
hideModal: true
})
}, 720)
},
fadeIn() {
this.animation.translateY(0).step()
this.setData({
animationData: this.animation.export()
})
},
fadeDown() {
this.animation.translateY(800).step()
this.setData({
animationData: this.animation.export(),
})
}
}
})
.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;
}
"usingComponents": {
"tab-scroll":"../../components/tabScroll/tabScroll",
},
<view class="box">
<tab-scroll typeList="{{typeList}}" bind:chooseType="chooseType"></tab-scroll>
</view>
page {
width: 100%;
height: auto;
overflow-y: auto;
background: #f7f7f7;
}
.box{
box-sizing: border-box;
width: 100%;
}
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)
},
})