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

  • 适配不同文字长度

  • 滑块始终精准居中

相关推荐
weixin_4713830310 小时前
由浅入深递归练习
前端·javascript·vue.js
喵个咪11 小时前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
前端·vue.js·react.js
柚子科技15 小时前
Vue3 响应式原理:我被 ref 和 reactive 坑了3次后终于搞懂了
前端·javascript·vue.js
大鱼前端15 小时前
Veaury:让Vue和React组件在同一应用中共存的神器
前端·vue.js·react.js
五月君_15 小时前
继 React、Vue 之后,Three.js 也有 Skills 了!AI 写 3D 终于不“晕”了
javascript·vue.js·人工智能·react.js·3d
蜡台17 小时前
Vue2 使用 typescript 教程
前端·vue.js·typescript
i220818 Faiz Ul18 小时前
在线预约导游|基于SSM+vue的在线预约导游系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·在线预约导游系统
felipeas18 小时前
uni-app day1
uni-app·notepad++
double_eggm18 小时前
微信小程序8
微信小程序·小程序