制作一个手机app顶部tab栏自带过渡效果

这篇文章展示了如何利用Vue.js和TailwindCSS创建一个带有平滑滚动效果的tab栏组件。组件包含了数据绑定、动态样式以及状态管理,通过监听激活项改变来更新tab栏样式和位置。同时,文章提到了如何在父组件中使用过渡效果和引入其他子组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看图,直接上代码

 

 使用技术 vue+tailwind

<template>
  <div
    class="w-full fixed z-10 h-16"
    style="background: #fff"
  >
    <div
      class="body flex justify-around w-full"
      style="background: #f6f7f8"
    >
      <div
        v-for="(item, index) in tabList"
        :key="index"
        @click="handChangeTag(index)"
        :style="activedItemIndex == index
              ? { color: '#EE9351' }
              : { color: '#1C1932' }
        "
        style="transition: all 0.5s ease-in-out; font-size: 14px"
      >
        {{ item }}
      </div>
      <div
        class="absolute -bottom-10 h-1 rounded-full"
        :style="{
                width: '4%',
                background: '#EE9351',
                left: left,
                transition: 'all 0.2s ease-in-out',
              }
        "
      ></div>
    </div>
  </div>
</template>
<script>
import bus from "@/components/station";

export default {
  name: "navtab",
  data() {
    return {
      tabList: ["任务", "会话", "进程", "详情", "卷宗"],
      left: "8%", //8,28,48,68,88
      activedItemIndex: 0,
      flagd: false,
    };
  },
  created() {
    if (this.theAged) {
      this.tabList = ["任务", "进程", "详情"];
      this.left = "14%";
    }
  },
  mounted() {
    this.activedItemIndex = this.$store.state.tagNo;
    // this.left = this.activedItemIndex * 20 + 8 + "%";

    this.left = this.theAged
      ? this.activedItemIndex * 34 + 14 + "%"
      : this.activedItemIndex * 20 + 8 + "%";
  }, 
  
  watch: {
    activedItemIndex(news, olds) {
      this.$store.state.tagNo = news;
      this.$emit("handChangeTag", news, olds);
    },
  },
  methods: {
    handChangeTag(e) {
      console.log(e);
      if (this.theAged) {
        this.left = e * 34 + 14 + "%";
      } else {
        this.left = e * 20 + 8 + "%";
      }
      this.activedItemIndex = e;
    },
  },
};
</script>

css样式为tailwind 这样自带平滑滚动效果的tab栏就做好了

引入时在组件中引入这个tab组件,使用transition标签使上下过渡更一致,内部的组件引入自己项目的组件就可以了

<template>
  <div class="bg case-panel">
    <nav-tab @handChangeTag="handChangeTag" :flag="flag"></nav-tab>
    <!-- <BottomNavTab v-if="index == 0" :flag="flag"></BottomNavTab> -->
    <transition mode="in-out">
      <div
          class="item w-full h-full pt-16"
          v-show="index == 0"
          style="background: #f6f7f8"
      >
        <task :flag="flag" :caseId="caseId"></task>
      </div>
    </transition>
    <transition mode="in-out" v-if="!$store.state.theAged">
      <div class="item w-full h-full pt-16" v-if="index == 1">
        <chat :flag="flag" ref="chat"></chat>
      </div>
    </transition>
    <transition mode="in-out">
      <div class="item w-full h-full pt-16" v-show="$store.state.theAged?index===1:index == 2">
        <process :flag="flag"></process>
      </div>
    </transition>
    <transition mode="in-out">
      <div class="item w-full h-full pt-16" v-show="$store.state.theAged?index===2:index == 3">
        <info :flag="flag" :caseId="caseId"></info>
      </div>
    </transition>
    <transition mode="in-out" v-if="!$store.state.theAged">
      <div class="item w-full h-full pt-16" v-show="index == 4">
        <file :flag="flag"></file>
      </div>
    </transition>
  </div>
</template>

<script>
import {getCaseInfo} from "@/api/caseApi";
import NavTab from "./components/navTab.vue";
import BottomNavTab from "./components/bottomNavTab.vue";
import Task from "./components/task.vue";
import Info from "./components/info.vue";
import File from "./components/file.vue";
import Process from "./components/process.vue";
import Chat from "./components/chat.vue";

export default {
  components: {NavTab, BottomNavTab, Task, Info, File, Process, Chat},
  data() {
    return {
      qian: null,
      index: 0,
      flag: true,
      sendMessageInfo: {},
      caseInfo: {},
      caseId: null,
    };
  },
  created() {
    if (this.$route.params.caseId) {
      this.$store.commit("setData", {
        caseId: this.$route.params.caseId,
      });
      this.caseId = this.$route.params.caseId;
    } else {
      this.caseId = this.$store.state.caseId;
    }
    this.index = this.$store.state.tagNo;
    this.flag = this.$store.state.showFlag;
    this.sendMessageInfo = this.$route.params.messageType;
    if (this.sendMessageInfo == "audioMessage") {
      this.$refs.chat.sendMeetingMessage(this.$route.params.list);
    }
  },
  methods: {
    handChangeTag(e, n) {
      this.index = e;
      this.$store.state.tagNo = e;
      if (e > n) {
        //next
        this.qian = true;
      } else {
        //back
        this.qian = false;
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.bg {
  min-height: 84vh;
  background: #f6f7f8;
}

@keyframes donghua {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }

  to {
    transform: translateX(0px);
    opacity: 1;
  }
}

.item {
  position: relative;
  z-index: 0;
}

.v-enter-active {
  animation: donghua 0.3s ease-in-out;
}

.v-leave-active {
  animation: donghua 0.3s ease-in-out reverse;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值