xc-app/components/tab-control/tab-control.vue

323 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- tabbar组件 -->
<template>
<view class="TabControl" :style="[tabControlStyle]">
<scroll-view scroll-x="true" :style="'background-color:'+bgc+';top:'+top+'px;'" :class="fixed?'fxied':''" :scroll-left='scrollLeft' scroll-with-animation id="tabcard">
<image src="@/static/signUp/ico_return@3x.png" class="goBackImg" mode="" @click="goBack" v-if="goBackImg"></image>
<view class="tabList" :style="[tabListStyle]">
<view
:class="'tabItem'+(currentIndex==index?' thisOpenSelect':'')"
:style="[tabItemStyle]"
v-for="(item,index) in values"
:id="'item'+index"
:key='index'
@click="_onClick(item, index)">
<view class="tabItemName">
<text :style="(currentIndex==index?'font-size:'+activeSize+'rpx;color:'+activeColor:'font-size:'+itemSize+'rpx')">{{ item.name }}</text>
<!-- 排序箭头显示 -->
<view
v-show='item.sort && item.sortType !== 1'
class="arrow"
:style="'transform: rotate(' + (([4, 2].indexOf(item.sortType) !== -1) ? '180' : '0') + 'deg);'" />
</view>
<!-- 激活下划线如果需要显示则sort不要设置 -->
<view v-if='activeLineShow' class="activeLine" :style="{'background-color': activeLineColor}"></view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name:'TabControl',
props:{
//是否显示返回箭头
goBackImg: {
type: Boolean,
default: false
},
// 当前激活项
current: {
type: Number,
default: 0
},
// tab 集合
values: {
type: Array,
default () {
return []
}
},
// 整体背景色
bgc:{
type: String,
default: '#fff'
},
// 是否开启固定位置
fixed: {
type: Boolean,
default: false
},
// 是否开启tabBar滚动
scrollFlag: {
type:Boolean,
default:false
},
// 激活下划线的宽度
lineWidth: {
type: Number,
default: 48
},
// tab 文本正常时的字体大小
itemSize: {
type: Number,
default: 28
},
// tab 文本激活时的字体大小
activeSize: {
type: Number,
default: 28
},
// tab 文本正常时的字体颜色
activeColor: {
type: String,
default: '#FE4066'
},
// 开启固定位置之后的top设置
top: {
type: Number,
default: 0
},
// 每个tab项是否等宽显示
isEqually: {
type: Boolean,
default: false
},
// 父级与tab项的高度
tabListHeight: {
type: [Number, String],
default: 40
},
// 是否显示激活下划线
activeLineShow: {
type: Boolean,
default: true
},
//下划线颜色
activeLineColor: {
type: String,
default: '#FE4066'
},
tabWrapNeedHeight: {
type: Boolean,
default: true
}
},
data() {
return {
currentIndex: 0,
windowWidth:0, //设备宽度
leftList:[], //选项距离左边的距离
widthList:[], //选项宽度
scrollLeft:0, //移动距离
newScroll:0, //上一次移动距离(用来判断是左滑还是右滑)
wornScroll:0, //上一次移动距离(用来判断是左滑还是右滑)
};
},
watch: {
current(val) {
if (val !== this.currentIndex) {
this.currentIndex = val
if(this.scrollFlag){
this.tabListScroll(val)
}
}
}
},
computed: {
tabItemStyle: function () {
const _style = {}
if (this.isEqually) {
_style['width'] = this.windowWidth/this.values.length + 'px'
_style['margin-right'] = 0
}
if (!this.activeLineShow) {
_style['height'] = '100%'
}
return _style
},
tabListStyle: function () {
const _style = {
height: this.tabListHeight + 'px'
}
if (this.isEqually) {
_style['display'] = 'flex'
_style['justify-content'] = 'space-between'
_style['padding-left'] = 0
}
return _style
},
tabControlStyle: function () {
const _style = {}
if (this.tabWrapNeedHeight) {
_style['height'] = this.tabListHeight + 'px'
}
return _style
}
},
created() {
this.currentIndex = this.current
if(this.scrollFlag){
setTimeout(()=>{
this.tabListScroll(this.current)
},300)
}
},
mounted(){
setTimeout(()=>{
uni.createSelectorQuery().in(this).select("#tabcard").boundingClientRect((res)=>{
this.$emit('getTabCardHeight', {height:res.height})
}).exec()
uni.getSystemInfo({
success: (res)=> {
this.windowWidth = res.windowWidth;
// console.log(this.windowWidth);
this.values.forEach((i,v)=>{
let info = uni.createSelectorQuery().in(this);
info.select("#item"+v).boundingClientRect((res)=>{
// 获取第一个元素到左边的距离
// if(v==0){
// this.startLenght = res.left
// }
this.widthList.push(res.width)
this.leftList.push(res.left)
}).exec()
})
// console.log(this.leftList)
// console.log(this.widthList)
}
});
})
},
methods: {
goBack(){
uni.navigateBack({
})
},
_onClick(item, index) {
this.$emit('clickItem', { currentIndex: index, ...item })
if (this.currentIndex !== index) {
this.currentIndex = index
// 开启滚动
if(this.scrollFlag){
this.tabListScroll(index)
}
}
},
// 选项移动
tabListScroll(index){
let scoll = 0;
this.wornScroll = index;
// this.wornScroll-this.newScroll>0 在向左滑 ←←←←←
if(this.wornScroll-this.newScroll>0){
for(let i = 0;i<this.leftList.length;i++){
if(i>1&&i==this.currentIndex){
scoll = this.leftList[i-1]
}
}
// console.log('在向左滑',scoll)
}else{
if(index>1){
for(let i = 0;i<this.leftList.length;i++){
if(i<index-1){
scoll = this.leftList[i]
}
}
}else{
scoll = 0
}
// console.log('在向右滑')
}
this.newScroll = this.wornScroll;
this.scrollLeft = scoll;
}
}
}
</script>
<style lang="scss" scoped>
.goBackImg{
width: 18upx;
height: 32upx;
position: absolute;
left: 30upx;
top: 30upx;
z-index: 999;
}
.TabControl {
.fxied {
position: fixed;
z-index: 2;
}
.tabList {
height: 80rpx;
padding-left: 24rpx;
white-space: nowrap;
text-align: center;
.tabItem {
position: relative;
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-right: 60rpx;
.tabItemName {
display: flex;
align-items: center;
justify-content: center;
text {
line-height: 44rpx;
color: #564F5F;
transition: all 0.3s ease 0s;
}
.arrow {
width: 10rpx;
height: 6rpx;
margin-left: 6rpx;
background: url('@/static/components/triangular_arrow.png');
background-size: 100% 100%;
// transform: rotate(180deg);
}
}
.activeLine {
width: 48rpx;
height: 8rpx;
border-radius: 4rpx;
// background-color: #FE4066;
margin: 8rpx auto 0;
opacity: 0;
transition: all 0.5s ease 0s;
}
}
.tabItem:first-child {
// margin-left: 22rpx;
}
.tabItem:last-child {
margin-right: 24rpx;
}
.thisOpenSelect {
text {
color: #333;
font-weight: 600;
}
.activeLine {
opacity: 1;
}
}
}
}
</style>