基于vue的tab栏切换组件
子组件
<template>
<div class="tabBarP">
<ul>
<li v-for="(item,index) in tabDatas.list" :key="item.id" ref="el" :class="{'active':item.isActive}" @click="swapStatus(item,index)">
{{ item.name }}
</li>
<div ref="mySelect" class="bar" :style="{'--left':left}" />
</ul>
</div>
</template>
<script>
export default {
props: ['tabData'], //父组件传进来的子组件需要的值
data() {
return {
tabDatas:this.tabData,
left:''
}
},
mounted() {
//如果父组件传了默认值则显示默认值,否则第一个值作为默认值
if(this.tabDatas.myStatus){//横线的滚动效果
this.left = this.tabDatas.list[this.tabDatas.myStatus].lp
}else{
this.left = '15%'
}
},
methods: {
swapStatus(item, index) {
this.tabDatas.list.forEach(el => {
this.$set(el, 'isActive', false)
})
this.$set(item, 'isActive', true)
this.$refs.mySelect.style.left = item.lp
this.$refs.mySelect.style.transition = 'All 0.4s ease-in-out'
this.$refs.el[index].style.transition = 'All 0.4s ease-in-out'
this.tabDatas.myStatus = item.myStatus
this.$emit('tab', this.tabDatas.myStatus)
}
}
}
</script>
<style lang="less" scoped>
.tabBarP{
position: fixed;
top:0rem;
left:0;
right:0;
height: auto;
background-color: #fff;
ul {
overflow: hidden;
height: 0.88rem;
li {
float: left;
width: 25%;
font-size: 0.24rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 500;
color: #999999;
text-align: center;
line-height: 0.88rem;
box-sizing: border-box;
}
.active{
font-family: PingFangSC-Medium, PingFang SC;
color:#3378FF;
font-size: 0.30rem;
line-height: 0.8rem;
}
.bar {
width: 0.3rem;
height: 0.05rem;
border-radius: .05rem;
background-color: #3378FF;
position: absolute;
bottom: 0.15rem;
left: var(--left);
margin-left: -0.38rem;
}
}
}
</style>
父组件
<template>
<div>
<tab-bar ref="tabBar" class="tabBar" :tab-data="tabData" @tab="swapShow" />
<div class="content">
{{ content }}
</div>
</div>
</template>
<script>
import TabBar from '@/components/public/tabBar'//引入子组件
export default {
components: {
TabBar
},
data() {
return {
tabData: {
myStatus: '',//高亮值
list: [//tab数量可自行调整增减
{ name: '全部', lp: '15%', myStatus: 0, isActive: false },
{ name: '结算中', lp: '40.5%', myStatus: 1, isActive: false },
{ name: '已结算', lp: '65.5%', myStatus: 2, isActive: false },
{ name: '退回', lp: '90.5%', myStatus: 3, isActive: false }
]
},
settlementList: ['全部', '结算中', '已结算', '退回'],
content: ''
}
},
computed: {},
created() {
if (Number(this.tabData.myStatus) === 2) {//如果有默认高亮值
this.$set(this.tabData.list[2], 'isActive', true)
this.content = this.settlementList[2]
} else {//如果没有,那么默认第一个高亮
this.$set(this.tabData.list[0], 'isActive', true)
this.content = this.settlementList[0]
}
},
mounted() {
},
methods: {
// 切换tab,调取子组件方法
swapShow(val) {
this.content = this.settlementList[val]
}
}
}
</script>
<style lang="less" scoped>
.content{
width: 7rem;
margin: 1.3rem 0.25rem 0rem 0.25rem;
font-size: 0.6rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 500;
background-color: #ddd;
text-align: center;
line-height: 200px;
border: 1px solid #ddd;
}
</style>
注意
实际应用中,一般内容部分都是根据接口返回值渲染的列表,当切换tab时候,直接传参数,获取不同数据就好。