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 数量可动态扩展

  • 适配不同文字长度

  • 滑块始终精准居中

相关推荐
用户19883424362212 小时前
在vue中,abortController调用导致的内存泄漏问题
vue.js
HackTwoHub6 小时前
AntiDebug Mcp、AI逆向绕过前端,Hook 加密接口,抓取 Vue 路由漏洞,接入 MCP 让 AI 自动化挖掘前端漏洞
前端·vue.js·人工智能·安全·web安全·网络安全·系统安全
李明卫杭州7 小时前
还在用 Vue2 的 $set?一文吃透 Observable 响应式原理与 Vue3 的 Proxy 重构
vue.js
英勇无比的消炎药7 小时前
层级选择不再手写联动:TinyVue Cascader 级联选择器上手
vue.js
摇滚侠7 小时前
SpringBoot3+Vue3 全套视频教程 61
vue.js
breeze jiang7 小时前
告别等待焦虑:Vue 3 + DeepSeek 实现 AI 打字机流式对话,用户体验提升立竿见影
vue.js·人工智能·ux
Listen·Rain8 小时前
Vue概述
前端·javascript·vue.js
尽兴-8 小时前
传统 Java/Vue 系统如何一步步接入 AI 维护
java·vue.js·人工智能·ai·大模型
张人玉9 小时前
基于Vue 3 + ECharts / ECharts-GL / echarts-wordcloud 的数据可视化大屏——地形与产业数据可视化大屏
vue.js·信息可视化·echarts
十铭忘9 小时前
Vue3实现Pixso中的钢笔工具3——梳理函数调用
前端·vue.js