| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  | <template> | 
					
						
							|  |  |  |  |   <view class="raised-tabbar"> | 
					
						
							|  |  |  |  |     <!-- 背景遮罩层,创建凸起效果 --> | 
					
						
							|  |  |  |  |     <view class="tabbar-bg"> | 
					
						
							|  |  |  |  |       <view class="raised-circle"></view> | 
					
						
							|  |  |  |  |     </view> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     <!-- TabBar内容 --> | 
					
						
							|  |  |  |  |     <view class="tabbar-content"> | 
					
						
							|  |  |  |  |       <!-- 左侧两个选项 --> | 
					
						
							|  |  |  |  |       <view | 
					
						
							|  |  |  |  |         v-for="(item, index) in leftItems" | 
					
						
							|  |  |  |  |         :key="index" | 
					
						
							|  |  |  |  |         class="tabbar-item" | 
					
						
							|  |  |  |  |         :class="{ active: current === index }" | 
					
						
							|  |  |  |  |         @click="tabbarChange(index)" | 
					
						
							|  |  |  |  |       > | 
					
						
							|  |  |  |  |         <view class="item-icon"> | 
					
						
							|  |  |  |  |           <image | 
					
						
							|  |  |  |  |             :src="current === index ? item.activeIcon : item.inactiveIcon" | 
					
						
							|  |  |  |  |             class="icon-normal" | 
					
						
							|  |  |  |  |           /> | 
					
						
							|  |  |  |  |           <view v-if="item.badge && item.badge > 0" class="badge">{{ | 
					
						
							|  |  |  |  |             item.badge | 
					
						
							|  |  |  |  |           }}</view> | 
					
						
							|  |  |  |  |         </view> | 
					
						
							|  |  |  |  |         <text class="item-text" :class="{ active: current === index }">{{ | 
					
						
							|  |  |  |  |           item.text | 
					
						
							|  |  |  |  |         }}</text> | 
					
						
							|  |  |  |  |       </view> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       <!-- 中间凸起的选项 --> | 
					
						
							|  |  |  |  |       <view | 
					
						
							|  |  |  |  |         class="tabbar-item center-item" | 
					
						
							|  |  |  |  |         :class="{ active: current === 2 }" | 
					
						
							|  |  |  |  |         @click="tabbarChange(2)" | 
					
						
							| 
									
										
										
										
											2025-09-16 14:37:35 +08:00
										 |  |  |  |         v-if="!newShareMember" | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  |       > | 
					
						
							|  |  |  |  |         <view class="center-icon-wrapper"> | 
					
						
							|  |  |  |  |           <view class="center-icon"> | 
					
						
							|  |  |  |  |             <image | 
					
						
							|  |  |  |  |               :src=" | 
					
						
							|  |  |  |  |                 current === 2 ? centerItem.activeIcon : centerItem.inactiveIcon | 
					
						
							|  |  |  |  |               " | 
					
						
							|  |  |  |  |               class="center-image" | 
					
						
							|  |  |  |  |             /> | 
					
						
							|  |  |  |  |           </view> | 
					
						
							|  |  |  |  |         </view> | 
					
						
							|  |  |  |  |         <text | 
					
						
							|  |  |  |  |           class="item-text center-text" | 
					
						
							|  |  |  |  |           :class="{ active: current === 2 }" | 
					
						
							|  |  |  |  |           >{{ centerItem.text }}</text | 
					
						
							|  |  |  |  |         > | 
					
						
							|  |  |  |  |       </view> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       <!-- 右侧两个选项 --> | 
					
						
							|  |  |  |  |       <view | 
					
						
							|  |  |  |  |         v-for="(item, index) in rightItems" | 
					
						
							|  |  |  |  |         :key="index + 3" | 
					
						
							|  |  |  |  |         class="tabbar-item" | 
					
						
							|  |  |  |  |         :class="{ active: current === index + 3 }" | 
					
						
							|  |  |  |  |         @click="tabbarChange(index + 3)" | 
					
						
							|  |  |  |  |       > | 
					
						
							|  |  |  |  |         <view class="item-icon"> | 
					
						
							|  |  |  |  |           <image | 
					
						
							|  |  |  |  |             :src="current === index + 3 ? item.activeIcon : item.inactiveIcon" | 
					
						
							|  |  |  |  |             class="icon-normal" | 
					
						
							|  |  |  |  |           /> | 
					
						
							|  |  |  |  |           <view v-if="item.badge && item.badge > 0" class="badge">{{ | 
					
						
							|  |  |  |  |             item.badge | 
					
						
							|  |  |  |  |           }}</view> | 
					
						
							|  |  |  |  |         </view> | 
					
						
							|  |  |  |  |         <text class="item-text" :class="{ active: current === index + 3 }">{{ | 
					
						
							|  |  |  |  |           item.text | 
					
						
							|  |  |  |  |         }}</text> | 
					
						
							|  |  |  |  |       </view> | 
					
						
							|  |  |  |  |     </view> | 
					
						
							|  |  |  |  |   </view> | 
					
						
							|  |  |  |  | </template> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <script> | 
					
						
							|  |  |  |  | import { mapGetters } from 'vuex' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | export default { | 
					
						
							|  |  |  |  |   name: 'RaisedTabbar', | 
					
						
							|  |  |  |  |   props: { | 
					
						
							|  |  |  |  |     current: { | 
					
						
							|  |  |  |  |       type: Number, | 
					
						
							|  |  |  |  |       default: 0, | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-09-16 14:37:35 +08:00
										 |  |  |  |   mounted() { | 
					
						
							|  |  |  |  |     this.newShareMember = uni.getStorageSync('User')?.loginType !== 0 | 
					
						
							|  |  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  |   data() { | 
					
						
							|  |  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2025-09-16 14:37:35 +08:00
										 |  |  |  |       newShareMember: false, | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  |       // 完整的路由列表
 | 
					
						
							|  |  |  |  |       list: [ | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '首页', | 
					
						
							|  |  |  |  |           path: 'pages/index/index', | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '会员专区', | 
					
						
							|  |  |  |  |           path: 'pages/specialArea/index', | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '个人推广', | 
					
						
							|  |  |  |  |           path: 'pages/mine/share/index', | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '购物车', | 
					
						
							|  |  |  |  |           path: 'pages/shoppingCar/index', | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '我的', | 
					
						
							|  |  |  |  |           path: 'pages/mine/index', | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |       ], | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   computed: { | 
					
						
							|  |  |  |  |     ...mapGetters(['shopCarLength']), | 
					
						
							|  |  |  |  |     // 左侧两个选项
 | 
					
						
							|  |  |  |  |     leftItems() { | 
					
						
							|  |  |  |  |       return [ | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '首页', | 
					
						
							|  |  |  |  |           activeIcon: require('@/static/images/one1.png'), | 
					
						
							|  |  |  |  |           inactiveIcon: require('@/static/images/one2.png'), | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '会员专区', | 
					
						
							|  |  |  |  |           activeIcon: require('@/static/images/five1.jpg'), | 
					
						
							|  |  |  |  |           inactiveIcon: require('@/static/images/five2.jpg'), | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |       ] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     // 中间凸起选项
 | 
					
						
							|  |  |  |  |     centerItem() { | 
					
						
							|  |  |  |  |       return { | 
					
						
							|  |  |  |  |         text: '个人推广', | 
					
						
							|  |  |  |  |         activeIcon: require('@/static/images/code.svg'), | 
					
						
							|  |  |  |  |         inactiveIcon: require('@/static/images/code.svg'), | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     // 右侧两个选项
 | 
					
						
							|  |  |  |  |     rightItems() { | 
					
						
							|  |  |  |  |       return [ | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '购物车', | 
					
						
							|  |  |  |  |           activeIcon: require('@/static/images/three1.png'), | 
					
						
							|  |  |  |  |           inactiveIcon: require('@/static/images/three2.png'), | 
					
						
							|  |  |  |  |           badge: this.shopCarLength, | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           text: '我的', | 
					
						
							|  |  |  |  |           activeIcon: require('@/static/images/fore1.png'), | 
					
						
							|  |  |  |  |           inactiveIcon: require('@/static/images/fore2.png'), | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |       ] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   methods: { | 
					
						
							|  |  |  |  |     tabbarChange(index) { | 
					
						
							|  |  |  |  |       this.$emit('change', index) | 
					
						
							|  |  |  |  |       uni.switchTab({ | 
					
						
							|  |  |  |  |         url: '/' + this.list[index].path, | 
					
						
							|  |  |  |  |       }) | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | </script> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <style lang="scss" scoped> | 
					
						
							|  |  |  |  | .raised-tabbar { | 
					
						
							|  |  |  |  |   position: fixed; | 
					
						
							|  |  |  |  |   bottom: 0; | 
					
						
							|  |  |  |  |   left: 0; | 
					
						
							|  |  |  |  |   right: 0; | 
					
						
							|  |  |  |  |   z-index: 1000; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   .tabbar-bg { | 
					
						
							|  |  |  |  |     position: absolute; | 
					
						
							|  |  |  |  |     bottom: 0; | 
					
						
							|  |  |  |  |     left: 0; | 
					
						
							|  |  |  |  |     right: 0; | 
					
						
							|  |  |  |  |     height: 60px; | 
					
						
							|  |  |  |  |     background: #ffffff; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 添加底部安全区域
 | 
					
						
							|  |  |  |  |     &::after { | 
					
						
							|  |  |  |  |       content: ''; | 
					
						
							|  |  |  |  |       position: absolute; | 
					
						
							|  |  |  |  |       bottom: -40px; | 
					
						
							|  |  |  |  |       left: 0; | 
					
						
							|  |  |  |  |       right: 0; | 
					
						
							|  |  |  |  |       height: env(safe-area-inset-bottom); | 
					
						
							|  |  |  |  |       background: #ffffff; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   .tabbar-content { | 
					
						
							|  |  |  |  |     position: relative; | 
					
						
							|  |  |  |  |     display: flex; | 
					
						
							|  |  |  |  |     align-items: flex-end; | 
					
						
							|  |  |  |  |     height: 60px; | 
					
						
							|  |  |  |  |     padding-bottom: 5px; | 
					
						
							|  |  |  |  |     background: transparent; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .tabbar-item { | 
					
						
							|  |  |  |  |       flex: 1; | 
					
						
							|  |  |  |  |       display: flex; | 
					
						
							|  |  |  |  |       flex-direction: column; | 
					
						
							|  |  |  |  |       align-items: center; | 
					
						
							|  |  |  |  |       justify-content: center; | 
					
						
							|  |  |  |  |       padding-bottom: 5px; | 
					
						
							|  |  |  |  |       position: relative; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       .item-icon { | 
					
						
							|  |  |  |  |         position: relative; | 
					
						
							|  |  |  |  |         margin-bottom: 2px; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         .icon-normal { | 
					
						
							|  |  |  |  |           width: 20px; | 
					
						
							|  |  |  |  |           height: 20px; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         .badge { | 
					
						
							|  |  |  |  |           position: absolute; | 
					
						
							|  |  |  |  |           top: -5px; | 
					
						
							|  |  |  |  |           right: -8px; | 
					
						
							|  |  |  |  |           background: #ff4757; | 
					
						
							|  |  |  |  |           color: white; | 
					
						
							|  |  |  |  |           border-radius: 50%; | 
					
						
							|  |  |  |  |           width: 16px; | 
					
						
							|  |  |  |  |           height: 16px; | 
					
						
							|  |  |  |  |           font-size: 10px; | 
					
						
							|  |  |  |  |           text-align: center; | 
					
						
							|  |  |  |  |           line-height: 16px; | 
					
						
							|  |  |  |  |           display: flex; | 
					
						
							|  |  |  |  |           align-items: center; | 
					
						
							|  |  |  |  |           justify-content: center; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       .item-text { | 
					
						
							|  |  |  |  |         font-size: 10px; | 
					
						
							|  |  |  |  |         color: #666666; | 
					
						
							|  |  |  |  |         line-height: 1.2; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         &.active { | 
					
						
							|  |  |  |  |           color: #333333; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       // 中间凸起的特殊样式
 | 
					
						
							|  |  |  |  |       &.center-item { | 
					
						
							|  |  |  |  |         position: relative; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         .center-icon-wrapper { | 
					
						
							|  |  |  |  |           position: absolute; | 
					
						
							| 
									
										
										
										
											2025-07-25 17:52:25 +08:00
										 |  |  |  |           top: -58rpx; | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  |           background: #fff; | 
					
						
							|  |  |  |  |           border-radius: 50%; | 
					
						
							|  |  |  |  |           font-size: 0; | 
					
						
							|  |  |  |  |           padding: 4rpx; | 
					
						
							| 
									
										
										
										
											2025-07-25 17:52:25 +08:00
										 |  |  |  |           z-index: 10; | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |           .center-icon { | 
					
						
							|  |  |  |  |             width: 92rpx; | 
					
						
							|  |  |  |  |             height: 92rpx; | 
					
						
							|  |  |  |  |             border-radius: 50%; | 
					
						
							|  |  |  |  |             display: flex; | 
					
						
							|  |  |  |  |             align-items: center; | 
					
						
							|  |  |  |  |             justify-content: center; | 
					
						
							|  |  |  |  |             // box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
 | 
					
						
							|  |  |  |  |             position: relative; | 
					
						
							|  |  |  |  |             // 添加呼吸动画
 | 
					
						
							| 
									
										
										
										
											2025-07-25 16:49:19 +08:00
										 |  |  |  |             // animation: breathe 3s ease-in-out infinite;
 | 
					
						
							| 
									
										
										
										
											2025-07-25 16:00:11 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             .center-image { | 
					
						
							|  |  |  |  |               width: 92rpx; | 
					
						
							|  |  |  |  |               height: 92rpx; | 
					
						
							|  |  |  |  |               // position: absolute;
 | 
					
						
							|  |  |  |  |               // top: -10rpx;
 | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 活跃状态
 | 
					
						
							|  |  |  |  |             // &.active {
 | 
					
						
							|  |  |  |  |             //   background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
 | 
					
						
							|  |  |  |  |             // }
 | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         .center-text { | 
					
						
							|  |  |  |  |           margin-top: 25px; | 
					
						
							|  |  |  |  |           font-size: 9px; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         &.active { | 
					
						
							|  |  |  |  |           .center-icon-wrapper .center-icon { | 
					
						
							|  |  |  |  |             // background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
 | 
					
						
							|  |  |  |  |             transform: scale(1.1); | 
					
						
							|  |  |  |  |             transition: all 0.3s ease; | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 呼吸动画关键帧
 | 
					
						
							|  |  |  |  | @keyframes breathe { | 
					
						
							|  |  |  |  |   0%, | 
					
						
							|  |  |  |  |   100% { | 
					
						
							|  |  |  |  |     transform: scale(1); | 
					
						
							|  |  |  |  |     // box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
 | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   50% { | 
					
						
							|  |  |  |  |     transform: scale(1.05); | 
					
						
							|  |  |  |  |     // box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
 | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | </style> |