volunteer-secondary/src/tabbar/index.vue

196 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup lang="ts">
// i-carbon-code
import type { CustomTabBarItem } from './config'
import { getShowAiStatus } from '@/service'
import { customTabbarEnable, needHideNativeTabbar, tabbarCacheEnable } from './config'
import { tabbarList, tabbarStore } from './store'
// #ifdef MP-WEIXIN
// 将自定义节点设置成虚拟的去掉自定义组件包裹层更加接近Vue组件的表现能更好的使用flex属性
defineOptions({
virtualHost: true,
})
// #endif
/**
* 中间的鼓包tabbarItem的点击事件
*/
function handleClickBulge() {
uni.showToast({
title: '点击了中间的鼓包tabbarItem',
icon: 'none',
})
}
function handleClick(index: number) {
const item = tabbarList[index]
if (item.isBulge) {
handleClickBulge()
return
}
// 点击原来的不做操作
if (item.openType !== 'navigateTo' && index === tabbarStore.curIdx) {
return
}
const url = item.pagePath
if (item.openType === 'navigateTo') {
uni.navigateTo({ url })
return
}
tabbarStore.setCurIdx(index)
if (tabbarCacheEnable) {
uni.switchTab({ url })
}
else {
uni.navigateTo({ url })
}
}
const aiShowStatus = ref("0")
function removeNavigateToItem() {
const index = tabbarList.findIndex(item => item.openType === 'navigateTo')
if (index !== -1) {
tabbarList.splice(index, 1)
}
}
function aiShowStatusFn() {
getShowAiStatus().then((resp) => {
if (resp.code === 200) {
aiShowStatus.value = resp.result.value
if (aiShowStatus.value === "0") {
removeNavigateToItem()
}
}
})
}
// #ifndef MP-WEIXIN
// 因为有了 custom:true 微信里面不需要多余的hide操作
onLoad(() => {
// 解决原生 tabBar 未隐藏导致有2个 tabBar 的问题
needHideNativeTabbar
&& uni.hideTabBar({
fail(err) {
console.log('hideTabBar fail: ', err)
},
success(res) {
// console.log('hideTabBar success: ', res)
},
})
})
// #endif
const activeColor = 'var(--wot-color-theme, #1890ff)'
const inactiveColor = '#666'
function getColorByIndex(index: number) {
return tabbarStore.curIdx === index ? activeColor : inactiveColor
}
function getImageByIndex(index: number, item: CustomTabBarItem) {
if (!item.iconActive) {
console.warn('image 模式下,需要配置 iconActive (高亮时的图片),否则无法切换高亮图片')
return item.icon
}
return tabbarStore.curIdx === index ? item.iconActive : item.icon
}
onBeforeMount(() => {
aiShowStatusFn()
})
</script>
<template>
<view v-if="customTabbarEnable" class="h-50px pb-safe">
<view class="border-and-fixed bg-white" @touchmove.stop.prevent>
<view class="h-50px flex items-center">
<view
v-for="(item, index) in tabbarList" :key="index"
class="flex flex-1 flex-col items-center justify-center"
:style="{ color: getColorByIndex(index) }"
@click="handleClick(index)"
>
<view v-if="item.isBulge" class="relative">
<!-- 中间一个鼓包tabbarItem的处理 -->
<view class="bulge h-200rpx w-200rpx">
<!-- TODO 2/2: 中间鼓包tabbarItem配置通常是一个图片或者icon点击触发业务逻辑 -->
<!-- 常见的是:扫描按钮、发布按钮、更多按钮等 -->
<image class="mt-6rpx h-200rpx w-200rpx" src="/static/tabbar/scan.png" />
</view>
</view>
<view v-else class="relative flex flex-col items-center justify-center px-3">
<template v-if="item.iconType === 'uiLib'">
<!-- TODO: 以下内容请根据选择的UI库自行替换 -->
<!-- 如:<wd-icon name="home" /> (https://wot-design-uni.cn/component/icon.html) -->
<!-- 如:<uv-icon name="home" /> (https://www.uvui.cn/components/icon.html) -->
<!-- 如:<sar-icon name="image" /> (https://sard.wzt.zone/sard-uniapp-docs/components/icon)(sar没有home图标^_^) -->
<sar-icon :name="item.icon" size="20" />
</template>
<template v-if="item.iconType === 'unocss' || item.iconType === 'iconfont'">
<view :class="item.icon" class="text-20px" />
</template>
<template v-if="item.iconType === 'image'">
<view v-if="item.openType !== 'navigateTo'" class="h-24px w-24px">
<image :src="getImageByIndex(index, item)" mode="scaleToFill" class="h-24px w-24px" />
</view>
<view v-if="item.openType === 'navigateTo' && aiShowStatus" class="h-48px w-42px">
<image :src="getImageByIndex(index, item)" mode="scaleToFill" class="h-48px w-42px" />
</view>
</template>
<view v-if="item.text" class="mt-2px text-14px">
{{ item.text }}
</view>
<!-- 角标显示 -->
<view v-if="item.badge">
<template v-if="item.badge === 'dot'">
<view class="absolute right-0 top-0 h-2 w-2 rounded-full bg-#f56c6c" />
</template>
<template v-else>
<view class="absolute top-0 box-border h-5 min-w-5 center rounded-full bg-#f56c6c px-1 text-center text-xs text-white -right-3">
{{ item.badge > 99 ? '99+' : item.badge }}
</view>
</template>
</view>
</view>
</view>
</view>
<view class="pb-safe" />
</view>
</view>
</template>
<style scoped lang="scss">
.border-and-fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
border-top: 1px solid #eee;
box-sizing: border-box;
}
//
.bulge {
position: absolute;
top: -20px;
left: 50%;
transform-origin: top center;
transform: translateX(-50%) scale(0.5) translateY(-33%);
display: flex;
justify-content: center;
align-items: center;
width: 250rpx;
height: 250rpx;
border-radius: 50%;
background-color: #fff;
box-shadow: inset 0 0 0 1px #fefefe;
&:active {
// opacity: 0.8;
}
}
</style>