sunrains-tabbar 自定义 TabBar 插件使用指南
点击体验h5端
点击查看安卓端录屏效果
📋 目录
-
1. 基础配置
-
2. pages.json 配置
-
3. 动态配置 TabBar
-
4. 数字角标功能
-
5. 小程序端特殊配置
-
6. 主题配置
-
7. page页跳转自定义tab页
-
8. 拓展底部tabbar类型,(切换、弹出、进入)页面
1. 基础配置
uts
App.uvue onLaunch 初始化
import {initDefaultTabItems} from '@/uni_modules/sunrains-tabbar/tabbar-config.uts'
onLaunch(() => {
console.log('App Launch')
initDefaultTabItems()
}
1.1 配置 tabbar-config.uts 文件
在插件根目录 tabbar-config.uts 文件中,配置注册全局tab组件和导航栏设置。
完整示例:
uts
import { setNavbarConfig, NavBarConfig, registerGlobalComponent, setDefaultTabItems, TabItem } from '@/uni_modules/sunrains-tabbar/utssdk/types.uts'
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:弹窗组件
registerGlobalComponent('home', Recommend)
registerGlobalComponent('order', Order)
registerGlobalComponent('mine', Mine)
registerGlobalComponent('detail', Detail)
// 2. 配置导航栏(不设置会使用默认配置)
setNavbarConfig(new NavBarConfig(true, 34, 'bold', '#333333', '#ffffff', "", 88))
//初始化默认tabbar区域按钮
export function initDefaultTabItems(){
/**
*
* 3. 设置默认 Tab 列表(至少设置一个固定的,也可以全部设置,其它可通过请求服务端接口动态配置),
* 或通过网络请求初始化 游客 显示哪些 有 角色的 按角色 初始化
* App.uvue onLaunch 初始化
import {initDefaultTabItems} from '@/uni_modules/sunrains-tabbar/tabbar-config.uts'
onLaunch(() => {
console.log('App Launch')
initDefaultTabItems()
}
*/
let home = new TabItem('home',"", 12, "red", "yellow", "bold", '首页', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage")
let mine = new TabItem('mine',"", 12, "red", "yellow", "bold", '我的', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage")
let items = getStoreLoginItems();
//判断是否登录
if(false || items != null){
setDefaultTabItems(items)
}else{
setDefaultTabItems([
home,mine
])
storeLoginItems([home,mine])
}
}
关键步骤说明:
- 导入组件:将所有需要作为 Tab 的页面组件导入
- 注册组件 :使用
registerGlobalComponent注册每个组件(第一个参数为唯一标识) - 配置导航栏:可选配置,根据项目需求调整
- 设置默认 Tab:至少配置一个固定 Tab,其余可动态添加
2. pages.json 配置
2.1 必需配置
必须在 pages.json 中配置自定义 TabBar 入口页面(必须放在第一个位置),tab页无需在pages.json中配置:
json
{
"path": "uni_modules/sunrains-tabbar/index",
"style": {
"navigationStyle": "custom"
}
}
2.2 完整示例
json
{
"pages": [
{
"path": "uni_modules/sunrains-tabbar/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 方法:
typescript
import { setTabBadge} from '@/uni_modules/sunrains-tabbar/utssdk/noticetab.uts'
// 设置算法 tab 的角标为 5
setTabBadge("order",5)
// 清除角标(设置为 0)
setTabBadge("order",0)
// 设置超过 99 显示 99+
setTabBadge("order",150)
方法二:初始化时设置
在创建 TabItem 时传入 badge 参数:
typescript
import { TabItem } from '@/uni_modules/sunrains-tabbar/utssdk/types.uts'
// 带角标的 tab
new TabItem(
'order',
'算法',
'/static/tab/main2.png',
'/static/tab/main2_active.png'
10 // badge 参数
)
// 不带角标的 tab
new TabItem(
'home',
'首页',
'/static/tab/main1.png',
'/static/tab/main1_active.png'
)
4.3 完整示例
以 文档后面 mine.uvue 页面为例,实现动态设置角标功能:
4.4 实际应用场景
场景 1:算法未读数
typescript
// 从服务端获取未读算法数
async function loadUnreadOrderCount() {
const res = await getOrderCount()
setTabBadge("order",res.data.count)
}
// 页面加载时调用
onShow(() => {
loadUnreadOrderCount()
})
场景 2:消息通知
typescript
// WebSocket 收到新消息
websocket.onMessage((msg) => {
if (msg.type === 'new_message') {
const currentBadge = getCurrentBadge('message')
setTabBadge("newMessage",currentBadge + 1)
}
})
场景 3:购物车数量
typescript
// 添加商品到购物车后更新角标
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 中配置:
vue
<<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 文件中配置主题:
typescript
import {
setNavbarConfig,
NavBarConfig,
registerGlobalComponent,
setDefaultTabItems,
TabItem,
setTabBarTheme,
TabBarTheme
} from '@/uni_modules/sunrains-tabbar/types.uts'
import { setTabPageTheme} from '@/uni_modules/sunrains-tabbar/utssdk/noticetab.uts'
let bgType : BgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/2.png"
//配置导航栏(可选,不设置会使用默认配置)
let navBarConfig : NavBarConfig = new NavBarConfig(
true, // 是否显示导航栏
34, // 字体大小
'bold', // 字体粗细
'#FFA500', // 文字颜色
'',// 背景颜色
"", //背景图片(支持网络图片)
90) // 导航栏高度
let tabbarIcon = new TabbarIcon(
"mine",//自定义组件唯一标识
//非选中图标
"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",
//选中图标
"/static/tab/main3_active.png",
24,//图标宽 单位 px
24,//图标高 单位 px
//文字颜色
12,
//非选中文字大小
"green",
//选择文字颜色
"white",
//选择文字粗细
"bold"
)
let tabbarIcons : Map<string,TabbarIcon> = new Map();
tabbarIcons.set("mine",tabbarIcon)
let tabbarStyle : TabbarStyle = new TabbarStyle(
//tabbar区域高度
120,
//tabbar区域背景
"rgba(21, 20, 31, 0.8)",
//tabbar图标文字样式
tabbarIcons)
let theme = new CustomTheme(bgType, bg, navBarConfig, tabbarStyle);
setTabPageTheme(theme)
6.3 动态修改主题
在任意页面通过调用 setTabPageTheme 方法动态修改主题:
typescript
import { setTabPageTheme} from '@/uni_modules/sunrains-tabbar/utssdk/noticetab.uts'
// 动态修改背景色和选中颜色
let theme = new CustomTheme(bgType, bg, navBarConfig, tabbarStyle);
setTabPageTheme(theme)
6.4 在页面中动态切换主题
以 mine.uvue 页面为例,实现主题切换功能:
vue
<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:#ff4d40">动态设置中心</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">设置角标</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 { TabItem, GLOBAL_COMPONENT_REGISTRY, CustomTheme, TabbarIcon, TabbarStyle, NavBarConfig } from '@/uni_modules/sunrains-tabbar/utssdk/types.uts'
import { setTabBadge,setTabbarColorHeight,refreshTabbar ,setTabPageTheme,closeTabPop,clearStorage} from '@/uni_modules/sunrains-tabbar/utssdk/noticetab.uts'
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 | null>(null)
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([
new TabItem('mine', "",12, "red", "yellow", "bold", '我的', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage")
]);
}
function refresh2() {
console.log("动态tabbar(首页、我的)")
refreshTabbar([
new TabItem('home', "",12, "red", "yellow", "bold", '首页', '/static/tab/main1.png', '/static/tab/main1_active.png',24,24,"tabPage"),
new TabItem('mine', "",12, "red", "yellow", "bold", '我的', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage")
])
}
function refresh3() {
console.log("动态tabbar(算法、我的)")
refreshTabbar( [
new TabItem('order', "",12, "red", "yellow", "bold", '算法', '/static/tab/main2.png', '/static/tab/main2_active.png',24,24,"tabPage"),
new TabItem('mine', "",12, "red", "yellow", "bold", '我的', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage")
])
}
function refresh4() {
console.log("动态tabbar(我的、算法、首页、弹出详情、进入详情)")
refreshTabbar([
new TabItem('mine', "",12, "red", "yellow", "bold", '我的', '/static/tab/main3.png', '/static/tab/main3_active.png',24,24,"tabPage"),
new TabItem('order', "",12, "red", "yellow", "bold", '算法', '/static/tab/main2.png', '/static/tab/main2_active.png',24,24,"tabPage"),
new TabItem('home', "",12, "red", "yellow", "bold", '首页', '/static/tab/main1.png',
'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',
24,24,"tabPage"
),
new TabItem('detail', "",12, "red", "yellow", "bold", '弹出详情', '/static/tab/main1.png',
'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',
24,24,"tabPop"
),
new TabItem('detail', "/pages/detail/detail",12, "red", "yellow", "bold", '进入详情', '/static/tab/main1.png',
'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',
24,24,"page"
)
])
}
function theme() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/2.png"
// let bg:string = "black"
let navBarConfig : NavBarConfig = new NavBarConfig(true, 34, 'bold', '#FFA500', "rgba(191, 191, 191, 0.5)", "", 90)
let tabbarIcon = new TabbarIcon("mine",
"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",
"/static/tab/main3_active.png",
24,24,
12,
"green",
"white",
"bold"
)
let tabbarIcons : Map<string, TabbarIcon> = new Map();
tabbarIcons.set("mine", tabbarIcon)
let tabbarStyle : TabbarStyle = new TabbarStyle(120, "rgba(21, 20, 31, 0.8)", tabbarIcons)
let theme = new CustomTheme(bgType, bg, navBarConfig, tabbarStyle);
setTabPageTheme(theme)
}
function theme2() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "/static/sm.jpg"
// let bg:string = "black"
let navBarConfig : NavBarConfig = new NavBarConfig(false, 34, 'bold', '#0c0c0c', "", "", 90)
let tabbarIcon = new TabbarIcon("mine",
"/static/aj.png",
"/static/aj1.png",
24,24,
20,
"green",
"red",
"bold"
)
let tabbarIcon1 = new TabbarIcon("home",
"https://static-mp-4c53170b-e5f8-453b-a634-afcb5cf07d59.next.bspapp.com/img/icon/豪横.gif",
"https://static-mp-4c53170b-e5f8-453b-a634-afcb5cf07d59.next.bspapp.com/img/icon/豪横.gif",
50,24,
16,
"black",
"yellow",
"bold"
)
let tabbarIcons : Map<string, TabbarIcon> = new Map();
tabbarIcons.set("mine", tabbarIcon)
tabbarIcons.set("home", tabbarIcon1)
let tabbarStyle : TabbarStyle = new TabbarStyle(120, "rgba(21, 20, 31, 0.4)", tabbarIcons)
let theme = new CustomTheme(bgType, bg, navBarConfig, tabbarStyle);
setTabPageTheme(theme)
}
function theme3() {
//主题背景类型
let bgType = "IMG"
//背景 如果是图片传图片路径 颜色则传 具体颜色
let bg : string = "https://static-mp-4c53170b-e5f8-453b-a634-afcb5cf07d59.next.bspapp.com/img/bizhi/端午1.png"
// let bg:string = "black"
let navBarConfig : NavBarConfig = new NavBarConfig(true, 34, 'bold', '#0c0c0c', "", "", 90)
let tabbarIcon = new TabbarIcon("mine",
"/static/aj.png",
"/static/aj1.png",
24,24,
16,
"white",
"red",
"bold"
)
let tabbarIcon1 = new TabbarIcon("home",
"/static/sy1.png",
"/static/sy.png",
50,24,
16,
"white",
"red",
"bold"
)
let tabbarIcon2 = new TabbarIcon("detail",
"/static/tab/main2_active.png",
"/static/tab/main2_active.png",
24,24,
16,
"red",
"red",
"bold"
)
let tabbarIcons : Map<string, TabbarIcon> = new Map();
tabbarIcons.set("mine", tabbarIcon)
tabbarIcons.set("home", tabbarIcon1)
tabbarIcons.set("detail", tabbarIcon2)
let tabbarStyle : TabbarStyle = new TabbarStyle(150, "rgba(10, 13, 31, 0.8)", tabbarIcons)
let theme = new CustomTheme(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;
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 页面为例,实现主题切换功能:
xml
<template>
<view class="detail-root">
<view class="detail-content">
<!--
<view>
<input v-model="content" placeholder="请输入。。" />
<text>{{sbase64}}</text>
<text>{{base64yostr}}</text>
</view> -->
<view class = "con">
<view class = "com">
<text>网络请求</text>
</view>
<view>
<button class="btn" type="primary" @click="req">访问testvoid</button>
<button class="btn" type="primary" @click="reqSm2">访问testSm2</button>
<button class="btn" type="primary" @click="reqSm4">访问testSm4</button>
<button class="btn" type="primary" @click="reqSm2Sm4">访问testreqSm2Sm4</button>
</view>
</view>
<view class = "con">
<view class = "com">
<text>跳转tab页</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/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;
}
.con{
margin:10px 0;
padding:10px;
background-color: #e3eda1;
}
.btn{
margin: 5px;
}
</style>
8 拓展底部tabbar类型,(切换、弹出、进入)页面
uts
let mine = new TabItem(
'mine', //组件或页面唯一标识
"", //组件或页面路径 当类型为 page 时不可为空,其它传空字符串即可
12,
"red",
"yellow",
"bold",
'我的',
'/static/tab/main3.png',
'/static/tab/main3_active.png',
24,//图标宽
24,//图标高
"tabPage" //tabbar 类型 tabPage:tab页面 tabPop:弹窗组件 page:普通页面
)
注: 类型为 tabPop 打开页面 可下滑关闭 或点击虚拟返回按键关闭 或 页面中调用方法 closeTabPop()关闭
方法导入 import { pageToTab} from "@/uni_modules/sunrains-tabbar/utssdk/noticetab.uts"
⚠️ 常见问题
Q1: 为什么小程序端需要单独配置?
A: 微信小程序不支持动态组件渲染,必须静态声明所有可能使用的组件。
Q2: 动态 Tab 刷新失败怎么办?
A: 检查以下几点:
- 组件是否在
tabbar-config.uts中正确注册 - 是否正确使用了
GLOBAL_COMPONENT_REGISTRY.get()获取组件 - TabItem 的参数是否完整且类型正确
Q3: 导航栏配置不生效?
A: 确保 setNavbarConfig() 在 setDefaultTabItems() 之前调用,或在应用启动时尽早调用。
Q4: 如何设置数字角标?
A: 使用 uni.$emit('setTabBadge', {"key": "tab_key", "badge": number}) 即可,详见第 4 章。
Q5: 角标设置后不显示怎么办?
A: 检查以下几点:
- badge 值是否大于 0(0 或负数不显示)
- tab key 是否正确(必须与 TabItem 的 key 一致)
- 是否重新赋值了整个数组(直接修改对象属性不会触发响应式)
Q6: 退出登录如何清除 tabbar相关缓存
A: 调用 noticetab.uts里的 clearStorage 方法
go
/**
* 清除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")
}
}