更新记录
1.0.1(2026-06-25)
1:数据结构优化,2:插件外部导入类型 统一为 import {****} from '@/uni_modules/sunrains-tabbar-pro/outType.uts'
1.0.0(2026-06-24)
sunrains-tabbar升级版(具体升级内容规划中,敬请期待)
平台兼容性
uni-app x(4.75)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| √ | × | √ |
sunrains-tabbar-pro 自定义 TabBar 插件使用指南
点击体验h5端
点击查看安卓端录屏效果
点击查看安卓端演示安装包
目录
- [1. 基础配置]
- [2. pages.json 配置]
- [3. 动态配置 TabBar]
- [4. 数字角标功能]
- [5. 小程序端特殊配置]
- [6. 主题配置]
- [7. page页跳转自定义tab页]
-
[8. 拓展底部tabbar类型,(切换、弹出、进入)页面]
1. 基础配置
App.uvue onLaunch 初始化
import {initDefaultTabItems} from '@/uni_modules/sunrains-tabbar-pro/outType.uts'
onLaunch(() => {
console.log('App Launch')
initDefaultTabItems()
}
1.1 配置 tabbar-config.uts 文件
在插件根目录 tabbar-config.uts 文件中,配置注册全局tab组件和导航栏设置。
完整示例:
import { setNavbarConfig, setComponentRegistry, setDefaultTabItems } from './utssdk/globalfile'
import { TabItemType } from "./utssdk/common/type/commontypes";
import { getStoreLoginItems, storeLoginItems } from './utssdk/handle'
//导入所有自定义tab页
import Recommend from '@/pages/home/recommend.uvue'
import Order from '@/pages/order/order.uvue'
import Mine from '@/pages/mine/mine.uvue'
import Detail from '@/pages/detail/detail.uvue'
//注册所有需要切换的tab页或需要弹出的页面 即类型为 tabPage:tab页面 tabPop:弹窗组件
setComponentRegistry('home', Recommend)
setComponentRegistry('order', Order)
setComponentRegistry('mine', Mine)
setComponentRegistry('detail', Detail)
// 2. 配置导航栏(不设置会使用默认配置)
setNavbarConfig({
showTitle: true,
titleFontSize: 34,
titleFontWeight: 'bold',
titleColor: '#333333',
navBarBackgroundColor: '#ffffff',
navBarBackgroundImage: "",
navBarHeight: 88
})
//初始化默认tabbar区域按钮
export function initDefaultTabItems() {
/**
*
* 3. 设置默认 Tab 列表(至少设置一个固定的,也可以全部设置,其它可通过请求服务端接口动态配置),
* 或通过网络请求初始化 游客 显示哪些 有 角色的 按角色 初始化
* App.uvue onLaunch 初始化
import {initDefaultTabItems} from '@/uni_modules/sunrains-tabbar-pro/tabbar-config.uts'
onLaunch(() => {
console.log('App Launch')
initDefaultTabItems()
}
*/
let home : TabItemType = {
key: 'home',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "black",
fontWeight: "bold",
name: '首页',
icon: '/static/tab/main1.png',
activeIcon: '/static/tab/main1_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
let mine:TabItemType =
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "black",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
let items = getStoreLoginItems();
//判断是否登录
if (false || items != null) {
setDefaultTabItems(items)
} else {
setDefaultTabItems([
home, mine
])
storeLoginItems([home, mine])
}
}
关键步骤说明:
- 导入组件:将所有需要作为 Tab 的页面组件导入
- 注册组件:使用
setComponentRegistry注册每个组件(第一个参数为唯一标识) - 配置导航栏:可选配置,根据项目需求调整
- 设置默认 Tab:至少配置一个固定 Tab,其余可动态添加
2. pages.json 配置
2.1 必需配置
必须在 pages.json 中配置自定义 TabBar 入口页面(必须放在第一个位置),tab页无需在pages.json中配置:
{
"path": "uni_modules/sunrains-tabbar/index",
"style": {
"navigationStyle": "custom"
}
}
2.2 完整示例
{
"pages": [
{
"path": "uni_modules/sunrains-tabbar-pro/utssdk/index",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/detail/detail",
"style": {
"navigationBarTitleText": "详情"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app x",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
注意事项:
- 自定义 TabBar 入口页面必须配置在
pages数组的第一位 - 所有 Tab 页面不需要在
pages中声明 navigationStyle设置为"custom"以隐藏原生导航栏
3. 动态配置 TabBar
3.1 使用场景
当需要根据用户权限、服务端配置等动态调整 TabBar 时,可以在任意页面触发刷新。
3.2 实现示例
以下面文档 mine.uvue 页面为例:
关键点:
- 使用 refreshTabbar方法触发 TabBar 刷新
- 确保所有动态 Tab 对应的组件已在
tabbar-config.uts中注册
4. 数字角标功能
4.1 功能说明
支持为任意 Tab 设置数字角标,用于显示未读消息数、待处理事项等。
特性:
- ✅ 动态设置/更新角标
- ✅ 超过 99 自动显示 "99+"
- ✅ 角标为 0 或 null 时不显示
- ✅ 响应式更新,立即生效
4.2 使用方法
方法一:通过调用方法设置(推荐)
在任意页面通过 调用 setTabBadge 方法:
import { setTabBadge} from '@/uni_modules/sunrains-tabbar-pro/outType'
// 设置算法 tab 的角标为 5
setTabBadge("order",5)
// 清除角标(设置为 0)
setTabBadge("order",0)
// 设置超过 99 显示 99+
setTabBadge("order",150)
方法二:初始化时设置
在创建 TabItem 时传入 badge 参数:
import { TabItem } from '@/uni_modules/sunrains-tabbar/utssdk/types.uts'
// 带角标的 tab
let mine:TabItemType =
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "black",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage",
badge: 20
}
// 不带角标的 tab
let mine:TabItemType =
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "black",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
4.3 完整示例
以 文档后面 mine.uvue 页面为例,实现动态设置角标功能:
4.4 实际应用场景
场景 1:算法未读数
// 从服务端获取未读算法数
async function loadUnreadOrderCount() {
const res = await getOrderCount()
setTabBadge("order",res.data.count)
}
// 页面加载时调用
onShow(() => {
loadUnreadOrderCount()
})
场景 2:消息通知
// WebSocket 收到新消息
websocket.onMessage((msg) => {
if (msg.type === 'new_message') {
const currentBadge = getCurrentBadge('message')
setTabBadge("newMessage",currentBadge + 1)
}
})
场景 3:购物车数量
// 添加商品到购物车后更新角标
function addToCart(product: Product) {
cartItems.push(product)
setTabBadge("cart",cartItems.length)
}
5. 小程序端特殊配置
4.1 配置 tab-content-renderer.uvue
注意: 仅在需要支持微信小程序时需要配置,App 端可忽略此步骤。
在 uni_modules/sunrains-tabbar/tab-content-renderer.uvue 中配置:
<template>
<view style="width: 100%; height: 100%;">
<Recommend v-if="currentTab === 'home'" style="width: 100%; height: 100%;" />
<Order v-if="currentTab === 'order'" style="width: 100%; height: 100%;" />
<Mine v-if="currentTab === 'mine'" style="width: 100%; height: 100%;" />
<Detail v-if="currentTab === 'detail'" style="width: 100%; height: 100%;" />
</view>
</template>
<script setup lang="uts">
import Recommend from '@/pages/home/recommend.uvue'
import Order from '@/pages/order/order.uvue'
import Mine from '@/pages/mine/mine.uvue'
import Detail from '@/pages/detail/detail.uvue'
interface Props {
currentTab: string
}
defineProps({
currentTab:{
type:String
}
})
</script>
配置说明:
- 条件编译:使用
#ifndef MP-WEIXIN和#ifdef MP-WEIXIN区分平台 - App 端:使用
<component :is="...">动态渲染组件 - 小程序端:必须静态导入并声明所有可能的 Tab 组件
- 导入位置:在
#ifdef MP-WEIXIN块内导入组件
6. 主题配置
6.1 主题功能说明
插件支持自定义 TabBar 的主题样式,支持网络背景图、本地图片背景图、纯颜色背景(支持rgba透明)、导航栏、tabbar区域背景、图标大小、图标(支持网络图标)、文字颜色、文字大小、等属性 满足不同项目的视觉需求。
主题特性:
- ✅ 支持全局主题配置
- ✅ 支持动态切换主题
- ✅ 支持自定义主题参数
6.2 初始化时配置主题
可在 tabbar-config.uts 文件中配置主题
6.3 动态切换主题
在任意页面通过调用 setTabPageTheme 方法动态切换主题:
import {CustomThemeType} from '@/uni_modules/sunrains-tabbar-pro/outType'
// 动态修改背景色和选中颜色
let theme : CustomThemeType = {
bgType: bgType,
bg: bg,
navBarConfig: navBarConfig,
tabbarStyle: tabbarStyle
}
setTabPageTheme(theme)
6.4 在页面中动态切换主题
以 mine.uvue 页面为例,实现主题切换功能:
<template>
<scroll-view direction="vertical" class="mine-page" show-scrollbar="false" enable-back-to-top="true"
refresher-enabled="true" refresher-default-style="none" refresher-background="rgba(232, 201, 183, 0.5)"
:refresher-triggered="data.refreshing2" refresher-max-drag-distance="200px"
@refresherpulling="onRefresherpulling2" @refresherrefresh="onRefresherrefresh2"
@refresherrestore="onRefresherrestore2">
<uni-refresh-box slot="refresher" :pulling-distance="data.pullingDistance2" :refreshing="data.refreshing2"
loading-class="loading-dark" text-class="uni-text-class-buildin"
style="flex-direction: column;height: 46px;padding-top: 6px;" pulling-text="继续下拉可刷新" loosing-text="释放后会刷新"
loading-text="奋力加载中..." />
<view class="page-title">
<text style="color:black;font-size: 26px;font-weight: 900;">动态设置中心</text>
</view>
<view class="tabbar">
<text class="title-text">tabbar设置</text>
<button class="tabbar-btn" @click="refresh1">动态tabbar(我的)</button>
<button class="tabbar-btn" @click="refresh2">动态tabbar(首页、我的)</button>
<button class="tabbar-btn" @click="refresh3">动态tabbar(算法、我的)</button>
<button class="tabbar-btn" @click="refresh4">动态tabbar(我的、算法、首页、弹出详情、进入详情)</button>
<text class="title-text">设置角标(示例只注册了 mine order home 任选一个填入)</text>
<input class="input-item" v-model="tabbar" placeholder="请输入tabbar" />
<input class="input-item" v-model="badge" placeholder="请输入角标" />
<button class="tabbar-btn" @click="setBadge">确定</button>
<button class="tabbar-btn" @click="theme">主题1</button>
<button class="tabbar-btn" @click="theme2">主题2</button>
<button class="tabbar-btn" @click="theme3">主题3</button>
<button class="tabbar-btn" @click="clear">clear</button>
<!-- <button class="tabbar-btn" type="default" @click="refresh">刷新</button> -->
<!-- <button type="default" @click="cPop">返回</button> -->
</view>
</scroll-view>
</template>
<script setup lang="uts">
import { ref, onMounted, onUnmounted } from 'vue'
import {
TabItemType, CustomThemeType, TabbarIconType, TabbarStyleType, NavBarConfigType,
setTabBadge, setTabbarColorHeight, refreshTabbar, setTabPageTheme, closeTabPop, clearStorage
} from '@/uni_modules/sunrains-tabbar-pro/outType'
function cPop() {
closeTabPop()
}
onMounted(() => {
console.log('【组件挂载====mine===】')
})
onUnmounted(() => {
console.log('【组件销毁====mine===】')
})
// 用于自动化测试的数据暴露 - 使用 reactive 将所有 ref 状态集中暴露
const data = reactive({
refreshing2: false,
pullingDistance2: 0
})
function onRefresherpulling2(e : RefresherEvent) {
data.pullingDistance2 = e.detail.dy
}
const refreshing = ref(false)
function onRefresherrefresh2() {
data.refreshing2 = true
console.log('触发刷新')
setTimeout(() => {
data.refreshing2 = false
console.log('刷新完成')
}, 1500)
}
function onRefresherrestore2() {
data.pullingDistance2 = 0
}
function onRefresherabort2() {
data.pullingDistance2 = 0
}
// 上拉触底加载
const loadMore = () => {
console.log("滚动到底部", "info")
}
function clear() {
clearStorage("all")
}
const bgColor = ref<string>('pink')
const tabHeight = ref<string>('120')
const badge = ref<string>('0')
const ss = ref<any>("");
// tab 选项配置
const tabbar = ref<string>("")
const selectedTab = ref<string>('mine')
const selectedTabIndex = ref<number>(0)
function setBadge() {
//动态设置指定tabbar 角标
const badgeNum = parseInt(badge.value)
if (isNaN(badgeNum)) {
uni.showToast({
title: '请输入有效数字',
icon: 'none'
})
return
}
setTabBadge(tabbar.value, badgeNum)
uni.showToast({
title: `已设置 ${tabbar.value} 角标为 ${badgeNum}`,
icon: 'success'
})
}
function setStyle() {
setTabbarColorHeight(bgColor.value, parseInt(tabHeight.value))
}
function refresh1() {
console.log("动态tabbar(我的)")
refreshTabbar([
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
]);
}
function refresh2() {
console.log("动态tabbar(首页、我的)")
refreshTabbar([
{
key: 'home',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '首页',
icon: '/static/tab/main1.png',
activeIcon: '/static/tab/main1_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
},
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
])
}
function refresh3() {
console.log("动态tabbar(算法、我的)")
refreshTabbar([
{
key: 'order',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '算法',
icon: '/static/tab/main2.png',
activeIcon: '/static/tab/main2_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
},
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
}
])
}
function refresh4() {
console.log("动态tabbar(我的、算法、首页、弹出详情、进入详情)")
refreshTabbar([
{
key: 'mine',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '我的',
icon: '/static/tab/main3.png',
activeIcon: '/static/tab/main3_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
},
{
key: 'order',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '算法',
icon: '/static/tab/main2.png',
activeIcon: '/static/tab/main2_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
},
{
key: 'home',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '首页',
icon: '/static/tab/main1.png',
activeIcon: '/static/tab/main1_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPage"
},
{
key: 'detail',
path: "",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '弹出详情',
icon: '/static/tab/main1.png',
activeIcon: '/static/tab/main1_active.png',
iconW: 24,
iconH: 24,
tabType: "tabPop"
},
{
key: 'detail',
path: "/pages/detail/detail",
fontSize: 12,
fontColor: "red",
activeFontColor: "yellow",
fontWeight: "bold",
name: '进入详情',
icon: '/static/tab/main1.png',
activeIcon: '/static/tab/main1_active.png',
iconW: 24,
iconH: 24,
tabType: "page"
}
])
}
function theme() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/2.png"
// let bg:string = "black"
let navBarConfig : NavBarConfigType = {
showTitle: true,
titleFontSize: 34,
titleFontWeight: 'bold',
titleColor: '#FFA500',
navBarBackgroundColor: "rgba(191, 191, 191, 0.5)",
navBarBackgroundImage: "",
navBarHeight: 90
}
let tabbarIcon : TabbarIconType = {
key: "mine",
icon: "https://gimg3.baidu.com/search/src=https%3A%2F%2Fpic.rmb.bdstatic.com%2Fbjh%2Fuser%2F779083e57f84a4ce5345b17aaf7f8459.jpeg&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=r1,1&n=0&g=4&er=404&q=100&maxorilen2heic=2000000?sec=1781283600&t=4feca8b5a1149e3ed0f28ee030f767b4",
activeIcon: "/static/tab/main3_active.png",
iconW: 24, iconH: 24,
fontSize: 12,
fontColor: "green",
activeFontColor: "white",
fontWeight: "bold"
}
let tabbarIcon1 : TabbarIconType = {
key: "home",
icon: "/static/豪横.gif",
activeIcon: "/static/豪横.gif",
iconW: 0, iconH: 0,
fontSize: 30,
fontColor: "green",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcons : Map<string, TabbarIconType> = new Map();
tabbarIcons.set("mine", tabbarIcon)
tabbarIcons.set("home", tabbarIcon1)
let tabbarStyle : TabbarStyleType = {
tabbarHeight: 120,
bgColor: "rgba(21, 20, 31, 0.8)",
tabbarIcons: tabbarIcons
}
let theme : CustomThemeType = {
bgType: bgType,
bg: bg,
navBarConfig: navBarConfig,
tabbarStyle: tabbarStyle
}
setTabPageTheme(theme)
}
function theme2() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/sm.jpg"
// let bg:string = "black"
let navBarConfig : NavBarConfigType = {
showTitle: false,
titleFontSize: 34,
titleFontWeight: 'bold',
titleColor: '#0c0c0c',
navBarBackgroundColor: "",
navBarBackgroundImage: "",
navBarHeight: 90
}
let tabbarIcon : TabbarIconType = {
key: "mine",
icon: "/static/aj.png",
activeIcon: "/static/aj1.png",
iconW: 24, iconH: 24,
fontSize: 20,
fontColor: "green",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcon3 : TabbarIconType = {
key: "order",
icon: "/static/tab/main2.png",
activeIcon: "/static/tab/main2_active.png",
iconW: 24, iconH: 24,
fontSize: 20,
fontColor: "green",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcon1 : TabbarIconType = {
key: "home",
icon: "/static/豪横.gif",
activeIcon: "/static/豪横.gif",
iconW: 90, iconH: 90,
fontSize: 0,
fontColor: "green",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcons : Map<string, TabbarIconType> = new Map();
tabbarIcons.set("mine", tabbarIcon)
tabbarIcons.set("home", tabbarIcon1)
tabbarIcons.set("order", tabbarIcon3)
let tabbarStyle : TabbarStyleType = { tabbarHeight: 150, bgColor: "rgba(21, 20, 31, 0.4)", tabbarIcons: tabbarIcons }
let theme : CustomThemeType = { bgType, bg, navBarConfig, tabbarStyle }
setTabPageTheme(theme)
}
function theme3() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/端午3.png"
// let bg:string = "black"
let navBarConfig : NavBarConfigType = {
showTitle: true,
titleFontSize: 34,
titleFontWeight: 'bold',
titleColor: '#0c0c0c',
navBarBackgroundColor: "",
navBarBackgroundImage: "",
navBarHeight: 90
}
let tabbarIcon : TabbarIconType = {
key: "mine",
icon: "/static/aj.png",
activeIcon: "/static/aj1.png",
iconW: 24, iconH: 24,
fontSize: 16,
fontColor: "white",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcon1 : TabbarIconType = {
key: "home",
icon: "/static/sy1.png",
activeIcon: "/static/sy.png",
iconW: 24, iconH: 24,
fontSize: 16,
fontColor: "white",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcon2 : TabbarIconType = {
key: "detail",
icon: "/static/tab/main2_active.png",
activeIcon: "/static/tab/main2_active.png",
iconW: 24, iconH: 24,
fontSize: 16,
fontColor: "red",
activeFontColor: "red",
fontWeight: "bold"
}
let tabbarIcons : Map<string, TabbarIconType> = new Map();
tabbarIcons.set("mine", tabbarIcon)
tabbarIcons.set("home", tabbarIcon1)
tabbarIcons.set("detail", tabbarIcon2)
let tabbarStyle : TabbarStyleType = { tabbarHeight: 150, bgColor: "rgba(10, 13, 31, 0.8)", tabbarIcons: tabbarIcons }
let theme : CustomThemeType = { bgType, bg, navBarConfig, tabbarStyle }
setTabPageTheme(theme)
}
function init() {
uni.stopPullDownRefresh()
console.log('stop onPullDownRefresh=====');
}
onPullDownRefresh(() => {
console.log('onPullDownRefresh=====');
init()
})
function refresh() {
uni.startPullDownRefresh({
success: () => {
console.log("1111")
}
});
init()
}
</script>
<style scoped lang="scss">
.mine-page {
height: 100%;
// border: 12px solid red;
background: rgba(249, 235, 241, 0.5);
margin: 5px;
}
.page-title {
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.title-text {
font-size: 18px;
font-weight: bold;
color: #333;
}
.tabbar {
// border: 2px solid cyan;
padding: 15px;
display: flex;
flex-direction: column;
}
.input-item {
height: 45px;
border: 1px solid #ccc;
border-radius: 6px;
padding-left: 10px;
background: #fff;
margin: 10px;
padding-left: 20px;
}
.picker-item {
height: 45px;
border: 1px solid #ccc;
border-radius: 6px;
background: #fff;
margin: 10px;
display: flex;
align-items: center;
}
.picker-display {
padding-left: 20px;
font-size: 16px;
color: #333;
}
.tabbar-btn {
margin-bottom: 10px;
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #e5e5e5;
padding: 16px 0;
font-size: 16px;
}
.tabbar-btn:last-child {
margin-bottom: 0;
}
</style>
6.5 主题配置注意事项
- 颜色格式:颜色值必须为有效的 CSS 颜色格式(如
#ffffff、rgb(255,255,255)等) - tabbar区域高度单位:高度值为数字类型,单位为 rpx
- 动态修改:通过
uni.$emit('setTheme', new CustomTheme(bgType, bg, navBarConfig, tabbarStyle))动态修改的主题会立即生效
7 page页跳转自定义tab页
使用 pageToTab 方法 跳转到tab页
以 detail.uvue 页面为例,实现主题切换功能:
<template>
<view class="detail-root">
<view class="detail-content">
<view class="con">
<view class="com">
<text>网络通信</text>
</view>
<view class="com1">
<view>
<text style="margin-left: 10px;">服务端(java)源码</text>
</view>
<view>
<uni-link style="margin-right: 10px;font-size: 20px;color: red;" blankFallback="copy-link-modal"
href="https://gitee.com/sunyinhuia/sunrains-java" target="_blank">
点击查看
</uni-link>
</view>
</view>
<view>
<button class="btn" type="primary" @click="req">不签名、不加密访问</button>
<button class="btn" type="primary" @click="reqSm2">签名访问</button>
<button class="btn" type="primary" @click="reqSm4">加密访问</button>
<button class="btn" type="primary" @click="reqSm2Sm4">签名、加密访问</button>
</view>
</view>
<view class="con">
<view class="com">
<text>跳转tab页(示例只注册了 mine order home 任选一个填入)</text>
</view>
<view>
<input style="height: 50px; border:1px solid grey;margin: 5px 0;" v-model="addr"
placeholder="输入跳转tabbar key" />
<button type="warn" @click="tz">跳转tab页</button>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import { stringToBase64, base64ToString, ReqApi } from "@/uni_modules/sunrains-request"
import { Response, FrontRequestVo } from "@/uni_modules/sunrains-common-type"
import { CustFailError, getComErrorInfo } from "@/uni_modules/sunrains-common-err"
import { pageToTab } from "@/uni_modules/sunrains-tabbar-pro/utssdk/noticetab.uts"
onMounted(() => {
console.log('【组件挂载====detail===】')
})
onUnmounted(() => {
console.log('【组件销毁====detail===】')
})
const addr = ref("")
function tz() {
if (addr.value.length < 1) {
uni.showToast({
title: '请输入跳转的tabbar key'
});
} else {
pageToTab(addr.value)
}
}
function fh() {
uni.navigateBack()
}
let priKey = "4a4a1d48fc284fe2fc43970641880554aed2f69fdfbea63257ea417af4e65802"
let pubKey = "0460e86263ec52b38a3da24c7a605055d14f8aa5c7855e4f4e19819f4f8a5b72181afd7aa4ab19255eb871eaedaba30fa18cd5c71693d3d76b030a04969bd1edfe"
const BASEURL = "http://192.168.1.9:8081"
type IRootType = {
name : string;
age : number;
}
type Builds = {
buildingNo : string,
sortNum : number,
buildAreaId : string,
id : string
}
async function req() {
let data : UTSJSONObject = {
name: "张三",
age: 18
}
try {
let vo : FrontRequestVo = {
method: 'GET',
url: BASEURL + "/test/get/cs1",
data: data,
header: null,
reqFlag: "void",
priKey: priKey,
pubKey: pubKey,
//method 为POST时 不能为null
contentType: "urlencoded",
timeout: null,
//当为上传文件时 文件路径参数不能为空
filePathParamName: null
}
const res = await ReqApi(vo)
console.log("####reqvoid==", res.data)
// console.log("####==",res)
} catch (err) {
uni.showToast({
title: err.message ?? "请求异常",
icon: "error"
})
console.log("-----", err)
return
};
}
//"sign"|"sm4Encrypt"|"signwithenSM2-Sm4Encrypt"|"void";
async function reqSm2() {
let data : UTSJSONObject = {
name: "张三",
age: 18
}
try {
let vo : FrontRequestVo = {
method: 'GET',
url: BASEURL + "/test/get/cs1",
data: data,
header: null,
reqFlag: "sign",
priKey: priKey,
pubKey: pubKey,
//method 为POST时 不能为null
contentType: "urlencoded",
timeout: null,
//当为上传文件时 文件路径参数不能为空
filePathParamName: null
}
const res = await ReqApi(vo)
console.log("####reqSm2==", res.data)
} catch (err) {
uni.showToast({
title: err.message ?? "请求异常",
icon: "error"
})
//#ifndef APP-ANDROID
const errMsg = (err as any).errMsg ?? "未知错误";
const errCode = (err as any).errCode ?? -1;
console.log('标准化错误码:', errMsg);
console.log('标准化错误信息:', errCode);
//#else
if (err instanceof UniError) {
let sa = err as UniError
console.log('sa==:', sa);
}
//#endif
console.log("-----", err)
return
};
}
async function reqSm4() {
let data : UTSJSONObject = {
name: "张三",
age: 18
}
try {
let vo : FrontRequestVo = {
method: 'POST',
url: BASEURL + "/test/post/cs1",
data: data,
header: null,
reqFlag: "sm4Encrypt",
priKey: priKey,
pubKey: pubKey,
//method 为POST时 不能为null
contentType: "urlencoded",
timeout: null,
//当为上传文件时 文件路径参数不能为空
filePathParamName: null
}
const res = await ReqApi(vo)
console.log("####reqSm4==", res.data)
} catch (err) {
console.log("####reqSm4 err==", err)
uni.showToast({
title: err.message ?? "",
icon: "error"
})
return
};
}
async function reqSm2Sm4() {
let data : UTSJSONObject = {
name: "张三",
age: 18
}
try {
let vo : FrontRequestVo = {
method: 'POST',
url: BASEURL + "/test/post/cs1",
data: data,
header: null,
reqFlag: "signwithenSM2-Sm4Encrypt",
priKey: priKey,
pubKey: pubKey,
//method 为POST时 不能为null
contentType: "urlencoded",
timeout: null,
//当为上传文件时 文件路径参数不能为空
filePathParamName: null
}
const res = await ReqApi(vo)
console.log("####reqSm2Sm4==", res.data)
} catch (err) {
console.log("-----", err)
return
};
}
const orderId = ref<string>('')
const orderStatus = ref<string>('')
const content = ref<string>('')
const sbase64 = computed(() => {
return stringToBase64(content.value)
})
const base64yostr = computed(() => {
return base64ToString(sbase64.value)
})
onLoad((options) => {
const opts = options as UTSJSONObject
const id = options?.["orderId"] as string | null
const status = options?.["status"] as string | null
if (id != null) {
orderId.value = id
}
if (status != null) {
orderStatus.value = status
}
console.log(`接收算法参数:ID=${orderId.value},状态=${orderStatus.value}`)
})
const goBack = () => {
uni.navigateBack()
}
function init() {
// uni.stopPullDownRefresh()
// console.log('stop onPullDownRefresh=====');
}
// onPullDownRefresh(() => {
// console.log('onPullDownRefresh=====');
// init()
// })
function refresh() {
uni.removeStorageSync("LOGINTABBARITEMS")
// uni.startPullDownRefresh({
// success:()=>{
// console.log("1111")
// }
// });
// init()
}
</script>
<style scoped>
.detail-root {
/* flex: 1;
display: flex;
flex-direction: column; */
background-color: #fff;
}
.status-bar {
height: 44px;
background-color: #ffffff;
}
.detail-header {
height: 44px;
background-color: #fff;
flex-direction: row;
align-items: center;
padding-left: 15px;
padding-right: 15px;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #eee;
}
.back-icon {
font-size: 18px;
color: #007aff;
margin-right: 10px;
}
.detail-title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.detail-content {
flex: 1;
padding: 20px;
}
.detail-item {
flex-direction: row;
margin-bottom: 20px;
align-items: center;
}
.label {
font-size: 15px;
color: #666;
width: 80px;
}
.value {
font-size: 15px;
color: #333;
font-weight: bold;
}
.detail-desc {
margin-top: 30px;
}
.com {
display: flex;
align-items: center;
margin: 10px 0;
}
.com1 {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-radius: 5px;
margin: 10px 10px;
background-color: #64e4e0
}
.con {
margin: 10px 0;
padding: 10px;
background-color: #e3eda1;
}
.btn {
margin: 5px;
}
</style>
8 拓展底部tabbar类型,(切换、弹出、进入)页面
/**
* path 组件或页面路径 当类型为 page 时不可为空,其它传空字符串即可
* tabType 类型 tabPage:tab页面 tabPop:弹窗组件 page:普通页面
*/
export type TabItemType = {
key : string;
path : string;
fontSize : number;
fontColor : string;
activeFontColor : string;
fontWeight : string;
name : string;
icon : string;
activeIcon : string;
iconW : number;
iconH : number;
tabType : string;
badge ?: number | null
}
注: 类型为 tabPop 打开页面 可右滑手势(当手机开启右滑手势时)关闭、 或点击虚拟返回按键关闭 或 页面中调用方法 closeTabPop()关闭
方法导入 import { pageToTab} from "@/uni_modules/sunrains-tabbar/outType"
⚠️ 常见问题
Q1: 为什么小程序端需要单独配置?
A: 微信小程序不支持动态组件渲染,必须静态声明所有可能使用的组件。
Q2: 动态 Tab 刷新失败怎么办?
A: 检查以下几点:
- 组件是否在
tabbar-config.uts中正确注册 - 是否正确使用了
getComponentRegistryByKey.get("key")获取组件 - TabItem 的参数是否完整且类型正确
Q3: 如何设置数字角标?
A: 使用 setTabBadge(key, badgeNum) 即可,详见第 4 章。
Q4: 角标设置后不显示怎么办?
A: 检查以下几点:
- badge 值是否大于 0(0 或负数不显示)
- tab key 是否正确(必须与 TabItem 的 key 一致)
- 是否重新赋值了整个数组(直接修改对象属性不会触发响应式)
Q5: 退出登录如何清除 tabbar相关缓存
A: 调用 clearStorage 方法
import {clearStorage} from '@/uni_modules/sunrains-tabbar-pro/outType'
/**
* 清除tabbar相关缓存
* all 所有
* theme 主题
* tabbarItems 所有tabbar
* badge 角标
*/
export function clearStorage(type:string){
switch (type){
case "theme":
uni.removeStorageSync("sunrains-tabbar-customtheme")
break;
case "tabbarItems":
uni.removeStorageSync("sunrains-tabbar-logintabbaritems")
break;
case "badge":
uni.removeStorageSync("sunrains-tabbar-tabbarbadges")
break;
default:
uni.removeStorageSync("sunrains-tabbar-customtheme")
uni.removeStorageSync("sunrains-tabbar-logintabbaritems")
uni.removeStorageSync("sunrains-tabbar-tabbarbadges")
}
}

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 24
赞赏 0
下载 12325685
赞赏 1923
赞赏
京公网安备:11010802035340号