luban-mall/components/nav-tab/nav-tab.vue

151 lines
3.5 KiB
Vue
Raw Normal View History

2022-07-08 08:15:29 +00:00
<template>
2022-07-18 05:35:14 +00:00
<scroll-view scroll-x="true" :scroll-left="tabsScrollLeft" @scroll="scroll">
<view class="pull-nav-btns" :class="type=='radio'?'search-btns':''" :style="{width:newWidth}" id="tab_list">
<view @tap="chooseEv(index,item.id)" id="tab_item" :class="currentIndex==index?'radio-btn active':'radio-btn'" v-for="(item,index) in list" v-if="type=='radio'">
<view class="radio"></view>
<text>{{item.name}}</text>
</view>
<view @tap="chooseEv(index,item.id)" id="tab_item" :style="{width:'220rpx',margin:'0 25rpx'}" :class="currentIndex==index?'btn active':'btn'" v-for="(item,index) in list" v-if="type=='list' && index<=maxNum && maxNum<=3">{{item.name}}</view>
<view @tap="chooseEv(index,item.id)" id="tab_item" :style="{width:'170rpx',margin:'0 20rpx'}" :class="currentIndex==index?'btn active':'btn'" v-for="(item,index) in list" v-if="type=='list' && index<=maxNum && maxNum>3">{{item.name}}</view>
2022-07-08 08:15:29 +00:00
</view>
2022-07-18 05:35:14 +00:00
</scroll-view>
2022-07-08 08:15:29 +00:00
</template>
<script>
export default {
name:'nav-tab',
props:{
list:{
type:Array,
default:()=>{
return []
}
},
type:{
type:String,
default:'list'
}, //展现方式
maxNum:{
2022-07-11 10:35:14 +00:00
type:Number,
2022-07-08 08:15:29 +00:00
default:2
2022-07-15 10:29:01 +00:00
},
newWidth:{
type:String,
default:''
2022-07-18 05:35:14 +00:00
},
2022-07-08 08:15:29 +00:00
},
data(){
return {
currentIndex:0, //当前位置
2022-07-18 05:35:14 +00:00
scrollLeft:0,
tabsScrollLeft:0,
styleData:{}, //样式控制
}
},
watch: {
list() {
this.setTabList()
},
value() {
this.currentIndex = this.value
this.setTabList()
2022-07-08 08:15:29 +00:00
}
},
methods:{
// 导航选择事件
chooseEv(index,id) {
if(this.currentIndex !== index){
this.currentIndex = index;
// 抛出事件
2022-07-18 05:35:14 +00:00
this.$emit('chooseEv',index,id);
this.setTabList();
2022-07-08 08:15:29 +00:00
}
2022-07-18 05:35:14 +00:00
},
setTabList() {
this.$nextTick(() => {
if (this.list.length > 0) {
this.setLeft()
}
})
},
setLeft() {
let lineLeft = 0;
this.getElementData('#tab_list', (data) => {
let list = data[0];
this.getElementData(`#tab_item`, (res) => {
let el = res[this.currentIndex]
lineLeft = el.width / 2 + (-list.left) + el.left - list.width / 2 - this.scrollLeft
this.tabsScrollLeft = this.scrollLeft + lineLeft
})
})
},
getElementData(el, callback) {
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => {
callback(data[0]);
});
},
//滚动
scroll(e) {
this.scrollLeft = e.detail.scrollLeft;
2022-07-08 08:15:29 +00:00
}
}
}
</script>
<style scoped>
.pull-nav-btns {
display: flex;
justify-content: center;
align-items: center;
2022-07-15 10:29:01 +00:00
min-width: 100%;
2022-07-08 08:15:29 +00:00
padding: 25rpx 0;
}
.pull-nav-btns .btn {
height: 66rpx;
border-radius: 10rpx;
line-height: 66rpx;
text-align: center;
font-size: 30rpx;
color: #000000;
}
.pull-nav-btns .btn:first-child{
2022-07-18 05:35:14 +00:00
margin-left: 0 !important;
2022-07-08 08:15:29 +00:00
}
.pull-nav-btns .btn:last-child{
2022-07-18 05:35:14 +00:00
margin-right: 0 !important;
2022-07-08 08:15:29 +00:00
}
.pull-nav-btns .btn.active {
background-color: #0073bc;
color: #FFFFFF;
}
.pull-nav-btns.search-btns{
justify-content: flex-start;
padding: 8rpx 0 20rpx;
}
.pull-nav-btns .radio-btn {
display: flex;
align-items: center;
margin-left: 40rpx;
line-height: 66rpx;
font-size: 30rpx;
color: #000000;
}
.pull-nav-btns .radio-btn .radio{
box-sizing: border-box;
width: 24rpx;
height: 24rpx;
margin-right: 12rpx;
border: 2rpx solid #333333;
border-radius: 100%;
}
.pull-nav-btns .radio-btn:first-child{
margin-left: 0;
}
.pull-nav-btns .radio-btn.active .radio{
border: 8rpx solid #0073bc;
}
</style>