Uniapp 自定義 Tabbar 實現教程

Uniapp 自定義 Tabbar 實現教程

    • 1. 簡介
    • 2. 實現步驟
      • 2.1 創建自定義 Tabbar 組件
      • 2.2 配置 pages.json
      • 3.1 路由映射
      • 3.2 樣式設計
      • 3.3 圖標處理
    • 4. 常見問題及解決方案
      • 4.1 頁面跳轉問題
      • 4.2 樣式適配問題
      • 4.3 性能優化
    • 5. 擴展功能
      • 5.1 添加徽標
      • 5.2 添加動畫效果
    • 6. 總結

1. 簡介

在 Uniapp 開發中,自定義 Tabbar 是一個常見的需求。本教程將詳細介紹如何實現一個美觀且功能完整的自定義 Tabbar,并分享在實現過程中可能遇到的問題和解決方案。

自定義圖示

2. 實現步驟

2.1 創建自定義 Tabbar 組件

首先,我們需要創建一個自定義的 Tabbar 組件。以下是完整的實現代碼:

<template><!-- 自定義 Tabbar 容器 --><view class="custom-tabbar"><!-- 遍歷 tabList 生成 Tabbar 項 --><view v-for="(item, index) in tabList" :key="index" class="tabbar-item" :class="{'tabbar-item-active': current === index}" @click="switchTab(item.pagePath)"><!-- 使用 Vant UI 的圖標組件 --><van-icon :name="current === index ? item.selectedIcon : item.icon" class="tabbar-icon" :class="{'tabbar-icon-active': current === index}" /><text>{{ item.text }}</text></view></view>
</template><script>
// 定義路由映射關系,用于快速查找當前頁面對應的索引
const TAB_ROUTES = {'/pages/index/index': 0,'/pages/detail/detail': 1,'/pages/course/course': 2,  '/pages/profile/profile': 3
};export default {data() {return {current: 0,  // 當前選中的 tab 索引tabList: [{pagePath: '/pages/index/index',text: '首頁',icon: 'home-o',selectedIcon: 'home-o'},{pagePath: '/pages/detail/detail',text: '詳情',icon: 'records',selectedIcon: 'records'},{pagePath: '/pages/course/course',  text: '課程',icon: 'clock-o',selectedIcon: 'clock-o'},{pagePath: '/pages/profile/profile',text: '我的',icon: 'contact',selectedIcon: 'contact'}]}},methods: {// 切換 tab 的方法switchTab(url) {uni.switchTab({ url });}},watch: {// 監聽路由變化,更新當前選中的 tab'$route.path': {immediate: true,handler(path) {this.current = TAB_ROUTES[path] || 0;}}}
}
</script><style>
/* Tabbar 容器樣式 */
.custom-tabbar {position: fixed;bottom: 0;left: 0;right: 0;height: 110rpx;display: flex;justify-content: space-around;align-items: center;background-color: #fff;border-top: 1rpx solid #e2e8f0;box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);z-index: 9999;padding-bottom: env(safe-area-inset-bottom);  /* 適配全面屏 */
}/* Tabbar 項基礎樣式 */
.tabbar-item {display: flex;flex-direction: column;align-items: center;justify-content: center;font-size: 24rpx;color: #64748b;padding: 10rpx 0;transition: all 0.2s ease;position: relative;
}/* 激活狀態樣式 */
.tabbar-item-active {color: #3b82f6;font-weight: 600;
}/* 點擊效果 */
.tabbar-item:active {transform: scale(0.95);
}/* 圖標樣式 */
:deep(.tabbar-icon) {font-size: 48rpx !important;margin-bottom: 4rpx;
}/* 激活狀態圖標樣式 */
:deep(.tabbar-icon-active) {color: #3b82f6 !important;
}/* 文字樣式 */
.tabbar-item text {margin-top: 6rpx;font-weight: 500;
}/* 底部指示條 */
.tabbar-item-active:before {content: '';position: absolute;bottom: -10rpx;left: 50%;transform: translateX(-50%);width: 16rpx;height: 3px;background: #3b82f6;border-radius: 3px;
}
</style>

2.2 配置 pages.json

pages.json 中需要禁用原生 Tabbar,并配置頁面路由:

{"tabBar": {"custom": true,  // 啟用自定義 Tabbar"list": [{"pagePath": "pages/index/index","text": "首頁"},{"pagePath": "pages/detail/detail","text": "詳情"},{"pagePath": "pages/course/course",  "text": "課程"},{"pagePath": "pages/profile/profile","text": "我的"}]}
}

3.1 路由映射

使用 TAB_ROUTES 對象來映射路由路徑和對應的索引值,這樣可以方便地管理當前選中的 tab:

const TAB_ROUTES = {'/pages/index/index': 0,'/pages/detail/detail': 1,'/pages/course/course': 2,  '/pages/profile/profile': 3
};

3.2 樣式設計

  • 使用 position: fixed 確保 Tabbar 固定在底部
  • 添加 env(safe-area-inset-bottom) 適配全面屏手機
  • 使用 box-shadow 添加陰影效果
  • 實現點擊縮放動畫效果
  • 添加底部指示條

3.3 圖標處理

使用 van-icon 組件(來自 Vant UI)來顯示圖標,通過 :class 動態切換選中狀態。

4. 常見問題及解決方案

4.1 頁面跳轉問題

問題:使用 uni.switchTab 跳轉時可能出現頁面不更新的情況。

解決方案

  • 確保在 pages.json 中正確配置了 tabBar
  • 使用 uni.switchTab 而不是 uni.navigateTo
  • watch 中監聽路由變化,及時更新選中狀態

4.2 樣式適配問題

問題:在不同機型上可能出現底部遮擋或樣式錯亂。

解決方案

  • 使用 env(safe-area-inset-bottom) 適配全面屏
  • 設置合適的 z-index 確保層級正確
  • 使用 rpx 單位確保在不同設備上顯示一致

4.3 性能優化

問題:頻繁切換可能導致性能問題。

解決方案

  • 使用 v-for 時添加 :key
  • 合理使用 watch 監聽路由變化
  • 避免在 Tabbar 中加載過多資源

5. 擴展功能

5.1 添加徽標

可以在 Tabbar 項上添加徽標,顯示未讀消息數量等:

<view class="tabbar-item"><van-icon :name="icon" /><text>{{ text }}</text><view v-if="badge" class="badge">{{ badge }}</view>
</view>

5.2 添加動畫效果

可以添加更豐富的動畫效果,如:

.tabbar-item {transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.tabbar-item:hover {transform: translateY(-5rpx);
}

6. 總結

通過以上步驟,我們實現了一個功能完整、樣式美觀的自定義 Tabbar。這個實現方案具有以下特點:

  1. 支持路由跳轉
  2. 適配不同機型
  3. 提供良好的視覺反饋
  4. 性能優化
  5. 易于擴展

作者:xuan
個人博客:https://blog.ybyq.wang
歡迎訪問我的博客,獲取更多技術文章和教程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94557.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94557.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94557.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JuiceFS存儲

因語雀與csdn markdown 格式有區別&#xff0c;請查看原文&#xff1a; https://www.yuque.com/dycloud/pss8ys 一、JuiceFS 介紹 1.1 JuiceFS 是什么 JuiceFS 是一款面向云環境設計的高性能 POSIX 文件系統&#xff0c;核心能力是將對象存儲轉化為全功能文件系統。它采用獨…

【HarmonyOS Next之旅】DevEco Studio使用指南(三十八) -> 構建HAR

目錄 1 -> 前言 2 -> 使用約束 3 -> 創建模塊 4 -> 構建HAR 4.1 -> 以debug模式構建HAR 4.2 -> 以release模式構建HAR 4.3 -> 構建字節碼格式的HAR 4.4 -> 對HAR進行簽名 1 -> 前言 構建模式&#xff1a;DevEco Studio默認提供debug和rele…

93、【OS】【Nuttx】【構建】cmake menuconfig 目標

【聲明】本博客所有內容均為個人業余時間創作&#xff0c;所述技術案例均來自公開開源項目&#xff08;如Github&#xff0c;Apache基金會&#xff09;&#xff0c;不涉及任何企業機密或未公開技術&#xff0c;如有侵權請聯系刪除 背景 接之前 blog 【OS】【Nuttx】【構建】cm…

React 表單處理:移動端輸入場景下的卡頓問題與防抖優化方案

文章目錄每日一句正能量前言一、問題場景與表現二、技術攻堅過程三、優化效果與經驗沉淀每日一句正能量 山再高&#xff0c;往上攀&#xff0c;總能登頂&#xff1b;路再長&#xff0c;走下去&#xff0c;終將到達。每日一勵&#xff0c;勇往直前。 前言 在移動端 React 項目開…

數據安全防護所需要的關鍵要素

數據安全防護是一個覆蓋數據全生命周期&#xff08;采集、存儲、傳輸、處理、銷毀&#xff09;、融合技術、管理、流程與人員的系統性工程。其核心目標是保障數據的??保密性&#xff08;Confidentiality&#xff09;、完整性&#xff08;Integrity&#xff09;、可用性&#…

【JavaEE】(8) 網絡原理 HTTP/HTTPS

一、什么是 HTTP 協議 上節說到&#xff0c;應用層的協議需要約定通信的內容和數據格式。我們可以自定義應用層協議&#xff0c;也可以基于現成的應用層協議進行開發。協議的種類很多&#xff0c;最常見的之一就是 HTTP&#xff0c;廣泛用于網站和手機 App。準確來說&#xff0…

C語言的數組與字符串練習題4

C語言的數組與字符串練習題4 16. 數組元素去重 題目描述: 編寫一個C程序,輸入一組整數存儲在數組中,去除數組中的重復元素,并輸出去重后的數組。 解題思路: 遍歷數組,對于每個元素,檢查它之前是否已經存在相同的元素。如果不存在,則將其保留;否則,跳過。可以使用一…

Transformers簡單介紹 - 來源于huggingface

Transformers介紹 - 來源于huggingface 文章目錄Transformers介紹 - 來源于huggingfaceTransformers能做什么pipeline()函數零樣本分類推理API完形填空命名實體識別問答摘要提取翻譯transformers是如何工作的transformers的具體組成注意力層機制transformers原始結構architectu…

template<typename R = void> 意義

在 C 中&#xff0c;template<typename R void> 表示定義一個模板參數 R&#xff0c;其默認類型為 void。這意味著&#xff1a;如果用戶沒有顯式指定 R&#xff0c;則 R 默認為 void。如果用戶顯式指定了 R&#xff08;如 template<typename R void> 后面跟著 &l…

國產3D大型裝配設計新突破①:圖紙打開設計雙加速 | 中望3D 2026

本文為CAD芯智庫整理&#xff0c;未經允許請勿復制、轉載&#xff01;在中望3D 2026的新版中&#xff0c;不僅在設計效率上進行了重大優化&#xff0c;更是在裝配方面實現了突破性的改進&#xff0c;讓每一個項目都能快速、精確地從概念變為現實。 中望3D2026亮點速遞裝配篇將…

游戲開發狀態機與行為樹的優缺點

在游戲開發中&#xff0c;狀態機&#xff08;Finite State Machine, FSM&#xff09; 和行為樹&#xff08;Behavior Tree, BT&#xff09; 是兩種常用的 AI 邏輯控制框架&#xff0c;分別適用于不同場景&#xff0c;其優缺點對比可從靈活性、維護成本、適用場景等多個維度分析…

Linux下ELF文件的介紹

目錄 1.溫故知新 2.ELF文件介紹 3.ELF文件組成 4.ELF文件形成到加載 5.連接過程 1.溫故知新 上一篇博客&#xff0c;我們介紹了我們的動靜態&#xff0c;知道了我們的庫其實也是文件&#xff0c;如果我們想寫一個庫也是可以的&#xff0c;我們的把我們的庫文件編譯成.o文件…

人工智能領域、圖歐科技、IMYAI智能助手2025年6月更新月報

2025年6月AI領域重要模型更新與平臺優化匯總 摘要&#xff1a; 本文匯總了2025年6月期間AI領域發布的多項重要模型更新及平臺功能優化信息&#xff0c;涵蓋Google Gemini、阿里通義萬相、字節豆包、百度文心一言、MiniMax海螺02、Google Veo3、快手可靈2.1、FLUX Kontext等模型…

從零開始學Express,理解服務器,路由于中間件

當我們初學前端時&#xff0c;常常只關注頁面效果和交互&#xff0c;但隨著項目復雜度提升&#xff0c;我們遲早會遇到“服務端”的問題&#xff1a;如何讓一個頁面的數據是從數據庫來的&#xff1f;怎么讓不同的用戶看到不同的內容&#xff1f;這時候&#xff0c;我們就需要一…

Codeforces Round 987 (Div. 2)

ABC 略D預處理出每個位置的前綴最大和后綴最小。從后向前枚舉&#xff0c;如果一個數無法后移&#xff0c;那么答案就是最大前綴&#xff0c;否則答案要不是前綴最大&#xff0c;要不就是這個數先移到前綴最大位置再移到能移到的最大的位置此處的答案。用線段樹維護#include<…

Javascript/ES6+/Typescript重點內容篇——手撕(待總結)

前端核心知識點梳理與面試題詳解 1. Promise 核心知識點 Promise 是異步編程的解決方案&#xff0c;用于處理異步操作三種狀態&#xff1a;pending&#xff08;進行中&#xff09;、fulfilled&#xff08;已成功&#xff09;、rejected&#xff08;已失敗&#xff09;狀態一旦改…

[自動化Adapt] 父子事件| 冗余過濾 | SQLite | SQLAlchemy | 會話工廠 | Alembic

第五章&#xff1a;事件處理與融合 歡迎回到OpenAdapt探索之旅~ 在第四章&#xff1a;系統配置中&#xff0c;我們掌握了如何定制化系統參數。更早的第一章&#xff1a;錄制引擎則展示了系統如何捕獲海量原始操作數據。 假設我們需要訓練機器人輸入"hello"一詞。原…

組合期權:跨式策略

文章目錄0.簡介1.買入跨式組合&#xff08;Long Straddle&#xff09;1.1 適用場景?1.2 合約選擇1.3 損益分析1.4 案例示范2.賣出跨式組合&#xff08;Short Straddle&#xff09;2.1 適用場景?2.2 合約選擇2.3 損益分析2.4 案例示范3.小結參考文獻0.簡介 跨式策略是一種交易…

Vue計算屬性詳解2

可寫計算屬性 計算屬性默認是只讀的,但在特殊場景下,我們可以創建"可寫"的計算屬性,通過同時提供getter和setter實現: <script setup>import { ref, computed } from vueconst firstName = ref(John)const lastName = ref(Doe)const fullName = computed(…

UniStorm 5.3.0 + Unity2022 + URP配置說明

一、前言 以前我用的是UniStorm3.0&#xff0c;主要用在內置管線里面&#xff0c;最近想在URP管線里面使用UniStorm天氣系統&#xff0c;于是弄了UniStorm5.3.0的包&#xff0c;在Unity2022.3的URP模式下配置&#xff0c;直接導入package&#xff0c;兩次宣告失敗。最后看了官方…