uni-app(Vue3)实现自定义 Tab 切换滑块效果(微信小程序)

在 uni-app 开发微信小程序时,系统自带的 tabs 组件往往难以满足复杂样式需求,例如:

  • 滑块需要居中对齐文字

  • 滑块宽度自定义

  • 切换时带动画

  • tab 数量动态变化

本文将介绍如何使用 uni-app + Vue3 组合式 API 实现一个自定义 Tab 切换组件,并实现 底部滑块跟随动画效果

一、效果说明

实现功能:

  • Tab 点击切换

  • 当前 tab 高亮

  • 底部滑块平滑移动

  • 滑块始终居中当前文字


二、Tab 结构

html 复制代码
<view class="tab-Con">
  <view class="tabs">
    <view
      v-for="(item, index) in tabsData"
      :key="index"
      class="tab-item"
      :id="'tab' + index"
      :class="{ active: current == index }"
      @click="changeTab(item.id,index)"
    >
      {{ item.petTypeName }}
    </view>

    <!-- 底部滑块 -->
    <view
      class="tab-line"
      :style="{ width: lineWidth + 'rpx', left: lineLeft + 'px' }"
    >
    </view>
  </view>
</view>

说明:

  • 每个 tab 绑定唯一 id:tab0、tab1

  • 滑块通过 left 动态移动

  • 当前激活 tab 通过 active 控制样式


三、数据结构

复制代码
javascript 复制代码
const tabsData = ref([
  { id: 1, petTypeName: "猫猫" },
  { id: 2, petTypeName: "狗狗" }
])

当前选中:

javascript 复制代码
const current = ref(0)
const currentPetType = ref(1)

四、点击切换逻辑

点击 tab 后:

  1. 更新当前选中 index

  2. DOM 更新完成后重新计算滑块位置

javascript 复制代码
const changeTab = (id, index) => {
  currentPetType.value = id
  current.value = index

  // DOM更新后测量
  nextTick(() => {
    updateLine()
  })
}

五、滑块位置计算(核心)

通过 SelectorQuery 获取当前 tab 的位置信息:

javascript 复制代码
const updateLine = () => {
  const index = current.value
  const query = uni.createSelectorQuery().in(instance)

  query.select('#tab' + index)
    .boundingClientRect((rect) => {
      if (rect) {
        // 计算滑块居中
        lineLeft.value = rect.left + rect.width / 2 - lineWidth / 4
      }
    })
    .exec()
}

计算逻辑:

滑块left = tab左边距 + tab宽度一半 - 滑块一半

这样滑块始终居中。


六、样式

css 复制代码
.tab-Con {
  border-bottom: 1px solid #DEE1E6;
  padding: 20rpx 0;
  position: relative;

  .tabs {
    display: flex;
    position: relative;
    width: 100%;
    height: 80rpx;
    justify-content: space-around;
    align-items: center;

    .tab-item {
      font-size: 30rpx;
      color: #565D6D;
      flex: 1;
      text-align: center;
    }

    .tab-item.active {
      color: #000;
      font-weight: bold;
    }

    .tab-line {
      position: absolute;
      bottom: 0;
      height: 4rpx;
      background-color: #000;
      transition: left 0.25s ease;
    }
  }
}

关键点:

复制代码

transition: left 0.25s ease;

实现滑动动画。


七、完整流程

组件运行流程:

  1. 页面加载完成执行 updateLine()

  2. 点击 tab

  3. 更新 current

  4. nextTick 等待 DOM 更新

  5. 重新计算滑块位置

  6. 触发动画滑动


八、总结

本文实现了一种 uni-app 微信小程序自定义 Tab 滑块方案,核心思路:

  • flex 布局实现 tab 排列

  • SelectorQuery 获取 tab 宽度位置

  • 计算滑块居中偏移

  • CSS transition 实现动画

该方案具有:

  • tab 数量可动态扩展

  • 适配不同文字长度

  • 滑块始终精准居中

相关推荐
墨染青竹梦悠然2 小时前
基于Django+vue的单词学习平台
前端·vue.js·后端·python·django·毕业设计·毕设
寒寒_3 小时前
使用Vue与Fabric.js创建图片标注工具
javascript·vue.js·fabric
萧曵 丶10 小时前
Vue 中父子组件之间最常用的业务交互场景
javascript·vue.js·交互
Amumu1213811 小时前
Vue3扩展(二)
前端·javascript·vue.js
泓博13 小时前
Android中仿照View selector自定义Compose Button
android·vue.js·elementui
+VX:Fegn089513 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
pas13614 小时前
45-mini-vue 实现代码生成三种联合类型
前端·javascript·vue.js
烟囱土著15 小时前
如何让相册「动」起来❓看这里❗
微信·微信小程序·小程序
boooooooom16 小时前
Vue v-for + key 优化封神:吃透就地复用与强制重排,再也不卡帧!
javascript·vue.js·面试