mpvue微信小程序实现tab切换横线滑动动画组件

学习前端快一年,对css动画方面研究甚少,一直想知道一些常见的动画是怎么实现的,也可以使项目体验变好。

需求:小程序常见的简单带线tab切换,线条滑动动画组件。

实现思路:v-for循环tab项,绝对定位线条,每次点击,运用'transform': 'translateX(**px)',切换位置,在加上一些过渡效果。

难点:点击获得每次移动的距离和线条的长度。

解决方案:运用微信api  wx.createSelectorQuery();获得字体元素据左边的距离及每次的移动距离,如图:(不会录动图,效果自己想象吧哈哈哈)

 

子组件代码 

<template>
  <div>
    <div class="nav_container">
      <!-- 线 -->
      <div
        class="active_bar"
        :style="{'background': color, 'transform': 'translateX(' + navOffset + 'px)', 'width': borderWidth + 'px', 'transition-duration': duration + 's'}"
      ></div>
      <div class="nav_item" v-for="(item, index) in nameList" :key="index" @click="chooseTab(item, index)">
        <div class="item_text" :id="'nav_'+ index" :style="{'color': currentTab == index ? color : ''}">
          {{ item.name }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    nameList: Array,
    color: String,
    duration: Number
  },
  data() {
    return {
      currentTab: 0,
      navOffset: 0,
      borderWidth: 0,
      left: 0
    }
  },
  methods: {
    chooseTab(item, index) {
      this.currentTab = index;
      this.$emit('change', item.id);
      this.compoutWidth(index);
    },
    compoutWidth(index = 0) {
      let selectId = `#nav_${index}`;
      const query = wx.createSelectorQuery();
      query.select(selectId).boundingClientRect(rect => {
        this.borderWidth = rect.width;
        this.navOffset = rect.left;
      }).exec();
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.compoutWidth();
    })
  }
}
</script>

<style lang="scss">
.nav_container {
  display: flex;
  position: relative;
  border-bottom: 0;
  background-color: #fff;
  .active_bar {
    position: absolute;
    width: 60rpx;
    height: 6rpx;
    bottom: 0%;
    transition: transform .2s cubic-bezier(.645,.045,.355,1);
  }
  .nav_item {
    display: flex;
    flex: 1;
    font-size: 30rpx;
    color: #777777;
    line-height: 88rpx;
    justify-content: center;
    .item_text {
      line-height: 88rpx;
    }
  }
}
</style>

参数含义

nameList:tab切换的项目和绑定的值


      nameList: [
        {
          name: '全部',
          id: 0
        },
        {
          name: '待付款',
          id: 1
        },
        {
          name: '待发货',
          id: 2
        },
        {
          name: '已发货',
          id: 3
        },
        {
          name: '已完成',
          id: 4
        }
      ],

color:线条颜色

duration:动画完成时长

父组件运用 

    <my-tabs :nameList="nameList" @change="tabChange" :color="primaryColor" :duration=".2"/>

// change事件

    tabChange(value) {
      console.log(value, 'value');
    }

 

踩坑

1. 以前写不带动画的tab线条时,用v-if实现每个字后面都有一条线,只是切换显隐状态,所以没有动画效果。要实现动画效果自始至终只有一条线,线条的宽度根据字体元素的宽度而定。看了vant-ui和elementUI的tab切换动画才明白过来的。

2. .exec()没加,获取不到rect的内容。

query.select(selectId).boundingClientRect(rect => {
        this.borderWidth = rect.width;
        this.navOffset = rect.left;
      }).exec();

备注

 这个组件非常简单,只是记录自己的学习过程和vantUI他们差的远了,还是要继续学习呀。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值