xlx_teacher_app/src/tabbar/index.vue

170 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
// 'i-carbon:home', 'i-carbon:user-multiple', 'i-carbon:user'
//
// icon: 'i-mingcute:home-5-line',
// activeIcon: 'i-mingcute:home-5-fill',
//
// icon: 'i-mingcute:group-2-line',
// activeIcon: 'i-mingcute:group-2-fill',
//
// icon: 'i-mingcute:user-4-line',
// activeIcon: 'i-mingcute:user-4-fill',
import { customTabbarList as _tabBarList, customTabbarEnable, nativeTabbarNeedHide, tabbarCacheEnable } from './config'
import { tabbarStore } from './store'
// #ifdef MP-WEIXIN
// 将自定义节点设置成虚拟的去掉自定义组件包裹层更加接近Vue组件的表现能更好的使用flex属性
defineOptions({
virtualHost: true,
})
// #endif
// TODO 1/2: 中间的鼓包tabbarItem的开关
const BULGE_ENABLE = false
function handleClickBulge() {
uni.showToast({
title: '点击了中间的鼓包tabbarItem',
icon: 'none',
})
}
/** tabbarList 里面的 path 从 pages.config.ts 得到 */
const tabbarList = _tabBarList.map(item => ({ ...item, path: `/${item.pagePath}` }))
if (BULGE_ENABLE) {
if (tabbarList.length % 2 === 1) {
console.error('tabbar 数量必须是偶数,否则样式很奇怪!!')
}
tabbarList.splice(tabbarList.length / 2, 0, {
isBulge: true,
} as any)
}
function handleClick(index: number) {
// 点击原来的不做操作
if (index === tabbarStore.curIdx) {
return
}
if (tabbarList[index].isBulge) {
handleClickBulge()
return
}
const url = tabbarList[index].path
tabbarStore.setCurIdx(index)
if (tabbarCacheEnable) {
uni.switchTab({ url })
}
else {
uni.navigateTo({ url })
}
}
onLoad(() => {
// 解决原生 tabBar 未隐藏导致有2个 tabBar 的问题
nativeTabbarNeedHide
&& uni.hideTabBar({
fail(err) {
console.log('hideTabBar fail: ', err)
},
success(res) {
// console.log('hideTabBar success: ', res)
},
})
})
// 每次页面显示时,根据当前路径自动同步 tabbar 选中状态
onShow(() => {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
if (currentPage?.route) {
// route 不带前导斜杠,与 pagePath 格式一致
tabbarStore.setAutoCurIdx(currentPage.route)
}
})
const activeColor = '#1890ff'
const inactiveColor = '#666'
function getColorByIndex(index: number) {
return tabbarStore.curIdx === index ? activeColor : inactiveColor
}
function getImageByIndex(index: number, item: { iconActive?: string, icon: string }) {
if (!item.iconActive) {
console.warn('image 模式下,需要配置 iconActive (高亮时的图片),否则无法切换高亮图片')
return item.icon
}
return tabbarStore.curIdx === index ? item.iconActive : item.icon
}
</script>
<template>
<view v-if="customTabbarEnable" class="relative z-50">
<view class="w-full pb-safe" style="height: 100rpx;" />
<view class="tabbar-wrap bg-white pb-safe">
<view class="h-full w-full flex items-center justify-around">
<view
v-for="(item, index) in tabbarList"
:key="index"
class="flex flex-1 flex-col items-center justify-center py-1 active:opacity-70"
@click="handleClick(index)"
>
<view class="relative flex items-center justify-center">
<view
class="transition-all duration-200"
:class="[
tabbarStore.curIdx === index ? item.activeIcon : item.icon,
tabbarStore.curIdx === index ? 'text-blue-600 tab-icon-active' : 'text-slate-400 tab-icon-normal',
]"
/>
<view v-if="item.badge" class="absolute z-10 -right-1 -top-1">
<view class="h-2 w-2 rounded-full bg-red-500 ring-2 ring-white" />
</view>
</view>
<text
class="tab-text mt-0.5 font-medium transition-colors duration-200"
:class="tabbarStore.curIdx === index ? 'text-blue-600' : 'text-slate-400'"
>
{{ item.text }}
</text>
</view>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
/* 核心容器高度固定为 100rpx (50px) */
.tabbar-wrap {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx; /* 标准高度 */
border-top: 1px solid #f8fafc;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.02);
z-index: 10;
}
/* 安全区适配 */
.pb-safe {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* 图标尺寸控制 */
.tab-icon-normal {
font-size: 44rpx; /* 22px */
}
.tab-icon-active {
font-size: 48rpx; /* 选中稍微大一点点 24px */
transform: translateY(-1px); /* 微微上浮增加灵动感 */
}
/* 文字尺寸控制 - text-xs (24rpx) 更小更精致 */
.tab-text {
font-size: 20rpx; /* 10px */
line-height: 1.2;
}
</style>