基于vue带动画效果tab切换组件封装

基于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时候,直接传参数,获取不同数据就好。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值