TabBar.vue
4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!--
* @Date: 2026-01-29 20:33:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-02-03 22:06:37
* @FilePath: /manulife-weapp/src/components/TabBar.vue
* @Description: 通用底部导航栏组件,用于页面底部固定导航栏,展示页面标题。
-->
<template>
<view
class="fixed bottom-0 left-0 w-full bg-white shadow-[0_-4rpx_16rpx_rgba(0,0,0,0.05)] pb-[env(safe-area-inset-bottom)] z-50">
<view class="flex items-center justify-around py-[32rpx]">
<view class="flex-1 flex flex-col items-center justify-center" v-for="(item, index) in tabs" :key="index"
@tap="handleTabClick(item)">
<view class="relative">
<IconFont :name="item.icon" :class="[current === item.key ? 'text-blue-600' : 'text-gray-400']" size="28" />
<!-- 红点提醒标记 -->
<view v-if="badges.includes(item.key)" class="tabbar-badge"></view>
</view>
<text class="text-[24rpx] mt-[8rpx]" :class="[current === item.key ? 'text-blue-600' : 'text-gray-400']">{{
item.label }}</text>
</view>
</view>
</view>
</template>
<script setup>
import { shallowRef, computed } from 'vue'
import IconFont from '@/components/IconFont.vue'
import { useGo } from '@/hooks/useGo'
import Taro from '@tarojs/taro'
import { useUserStore } from '@/stores/user'
const props = defineProps({
current: {
type: String,
default: 'home'
}
})
const go = useGo()
const userStore = useUserStore()
// 自动从 user store 读取红点状态
const badges = computed(() => userStore.tabBarBadges)
const tabs = shallowRef([
{
key: 'home',
label: '首页',
icon: 'home',
path: '/pages/index/index'
},
{
key: 'ai',
label: 'AI答疑',
icon: 'service',
path: '/pages/ai/index'
},
{
key: 'me',
label: '我的',
icon: 'my',
path: '/pages/mine/index'
}
])
const handleTabClick = (item) => {
if (item.key === props.current) return
if (item.key === 'home') {
go(item.path)
} else if (item.key === 'me') {
// Check if 'me' page exists, otherwise show toast or just go
// For now, assuming me page might not exist or we just navigate
// go(item.path)
// Based on existing logic in index.vue:
// Taro.redirectTo({ url: '/pages/me/index' });
// But wait, standard tab bar usually uses switchTab or redirectTo.
// Since this is a custom tab bar, we use useGo (which uses navigateTo usually).
// Ideally for tab switching we might want reLaunch or redirectTo to avoid stack buildup.
// However, useGo defaults to navigateTo.
// Let's use reLaunch to simulate tab switching behavior if it's a "tab bar"
// Actually, let's look at index.vue logic:
// if (item.key === 'me') Taro.redirectTo({ url: '/pages/me/index' });
// if (item.key === 'ai') Taro.showToast({ title: '功能开发中', icon: 'none' });
// I will replicate this logic for now but make it more generic if possible.
// Since 'me' and 'ai' might not be fully implemented, I will stick to what I know.
// But 'onboarding' and 'signing' pages use this tab bar too.
// If we are on 'onboarding' (which is seemingly a sub-page but has a tab bar),
// clicking 'Home' should probably go back to Home.
Taro.reLaunch({ url: item.path })
} else if (item.key === 'ai') {
// 跳转到腾讯元宝AI小程序(定制版)
Taro.navigateToMiniProgram({
appId: 'wxd5201eb08d2fa15c', // 腾讯元宝小程序 AppID
path: 'pages/agentChat/index?showAuthDirectly=1&agentId=sOySYp2PV9qa', // 拼接查询参数到路径中
envVersion: 'release', // 打开正式版
success: (res) => {
console.log('跳转元宝小程序成功', res)
},
fail: (err) => {
console.error('跳转元宝小程序失败', err)
Taro.showToast({
title: '跳转失败,请稍后重试',
icon: 'none'
})
}
})
}
}
</script>
<style lang="less">
/* 红点提醒标记样式 */
.tabbar-badge {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 16rpx;
height: 16rpx;
background-color: #ff4d4f;
border-radius: 50%;
border: 2rpx solid #fff;
box-shadow: 0 2rpx 8rpx rgba(255, 77, 79, 0.3);
z-index: 1;
}
</style>