168 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			168 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
| 
								 | 
							
								<template>
							 | 
						||
| 
								 | 
							
									<view class="custom-tab-bar">
							 | 
						||
| 
								 | 
							
										<view class="tab-bar-border"></view>
							 | 
						||
| 
								 | 
							
										<view 
							 | 
						||
| 
								 | 
							
											class="tab-bar-item" 
							 | 
						||
| 
								 | 
							
											v-for="(item, index) in tabList" 
							 | 
						||
| 
								 | 
							
											:key="index" 
							 | 
						||
| 
								 | 
							
											@click="switchTab(item, index)"
							 | 
						||
| 
								 | 
							
										>
							 | 
						||
| 
								 | 
							
											<view class="item-container" :class="{ active: currentIndex === index }">
							 | 
						||
| 
								 | 
							
												<view class="icon-container">
							 | 
						||
| 
								 | 
							
													<image :src="currentIndex === index ? item.selectedIconPath : item.iconPath" class="tab-icon"></image>
							 | 
						||
| 
								 | 
							
													<!-- 添加消息提示点 -->
							 | 
						||
| 
								 | 
							
													<view v-if="item.isDot && index !== currentIndex" class="tab-badge"></view>
							 | 
						||
| 
								 | 
							
													<view v-if="item.count && item.count > 0 && index !== currentIndex" class="tab-badge-count">{{item.count}}</view>
							 | 
						||
| 
								 | 
							
												</view>
							 | 
						||
| 
								 | 
							
												<text class="tab-text" :class="{ active: currentIndex === index }">{{ item.text }}</text>
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												<!-- 添加活跃项的动画效果 -->
							 | 
						||
| 
								 | 
							
												<view v-if="currentIndex === index" class="active-indicator"></view>
							 | 
						||
| 
								 | 
							
											</view>
							 | 
						||
| 
								 | 
							
										</view>
							 | 
						||
| 
								 | 
							
									</view>
							 | 
						||
| 
								 | 
							
								</template>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script>
							 | 
						||
| 
								 | 
							
									export default {
							 | 
						||
| 
								 | 
							
										data() {
							 | 
						||
| 
								 | 
							
											return {
							 | 
						||
| 
								 | 
							
												currentIndex: 0,
							 | 
						||
| 
								 | 
							
												tabList: []
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										created() {
							 | 
						||
| 
								 | 
							
											// 从Vuex获取tabBar配置
							 | 
						||
| 
								 | 
							
											this.tabList = this.vuex_tabbar;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											// 根据当前页面路径设置激活项
							 | 
						||
| 
								 | 
							
											const pages = getCurrentPages();
							 | 
						||
| 
								 | 
							
											const currentPage = pages[pages.length - 1];
							 | 
						||
| 
								 | 
							
											const currentPath = '/' + currentPage.route;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											this.tabList.forEach((item, index) => {
							 | 
						||
| 
								 | 
							
												// 移除前导斜杠以匹配路由
							 | 
						||
| 
								 | 
							
												const itemPath = item.pagePath.startsWith('/') ? item.pagePath.substring(1) : item.pagePath;
							 | 
						||
| 
								 | 
							
												if (itemPath === currentPage.route) {
							 | 
						||
| 
								 | 
							
													this.currentIndex = index;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										methods: {
							 | 
						||
| 
								 | 
							
											switchTab(item, index) {
							 | 
						||
| 
								 | 
							
												if (this.currentIndex === index) return;
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												this.currentIndex = index;
							 | 
						||
| 
								 | 
							
												// 移除前导斜杠如果存在
							 | 
						||
| 
								 | 
							
												const pagePath = item.pagePath.startsWith('/') ? item.pagePath : '/' + item.pagePath;
							 | 
						||
| 
								 | 
							
												uni.switchTab({
							 | 
						||
| 
								 | 
							
													url: pagePath
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<style lang="scss" scoped>
							 | 
						||
| 
								 | 
							
									.custom-tab-bar {
							 | 
						||
| 
								 | 
							
										position: fixed;
							 | 
						||
| 
								 | 
							
										bottom: 0;
							 | 
						||
| 
								 | 
							
										left: 0;
							 | 
						||
| 
								 | 
							
										right: 0;
							 | 
						||
| 
								 | 
							
										height: 56px;
							 | 
						||
| 
								 | 
							
										background-color: #ffffff;
							 | 
						||
| 
								 | 
							
										display: flex;
							 | 
						||
| 
								 | 
							
										padding-bottom: env(safe-area-inset-bottom);
							 | 
						||
| 
								 | 
							
										box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.05);
							 | 
						||
| 
								 | 
							
										z-index: 999;
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										.tab-bar-border {
							 | 
						||
| 
								 | 
							
											position: absolute;
							 | 
						||
| 
								 | 
							
											left: 0;
							 | 
						||
| 
								 | 
							
											top: 0;
							 | 
						||
| 
								 | 
							
											width: 100%;
							 | 
						||
| 
								 | 
							
											height: 1px;
							 | 
						||
| 
								 | 
							
											background-color: #f5f5f5;
							 | 
						||
| 
								 | 
							
											transform: scaleY(0.5);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										.tab-bar-item {
							 | 
						||
| 
								 | 
							
											flex: 1;
							 | 
						||
| 
								 | 
							
											display: flex;
							 | 
						||
| 
								 | 
							
											justify-content: center;
							 | 
						||
| 
								 | 
							
											align-items: center;
							 | 
						||
| 
								 | 
							
											height: 100%;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											.item-container {
							 | 
						||
| 
								 | 
							
												display: flex;
							 | 
						||
| 
								 | 
							
												flex-direction: column;
							 | 
						||
| 
								 | 
							
												align-items: center;
							 | 
						||
| 
								 | 
							
												justify-content: center;
							 | 
						||
| 
								 | 
							
												position: relative;
							 | 
						||
| 
								 | 
							
												padding: 5px 0;
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												&.active {
							 | 
						||
| 
								 | 
							
													transform: scale(1.05);
							 | 
						||
| 
								 | 
							
													transition: all 0.2s ease;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												.icon-container {
							 | 
						||
| 
								 | 
							
													position: relative;
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
													.tab-icon {
							 | 
						||
| 
								 | 
							
														width: 24px;
							 | 
						||
| 
								 | 
							
														height: 24px;
							 | 
						||
| 
								 | 
							
														margin-bottom: 3px;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
													.tab-badge {
							 | 
						||
| 
								 | 
							
														position: absolute;
							 | 
						||
| 
								 | 
							
														top: -2px;
							 | 
						||
| 
								 | 
							
														right: -2px;
							 | 
						||
| 
								 | 
							
														width: 8px;
							 | 
						||
| 
								 | 
							
														height: 8px;
							 | 
						||
| 
								 | 
							
														border-radius: 50%;
							 | 
						||
| 
								 | 
							
														background-color: #ff5252;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
													.tab-badge-count {
							 | 
						||
| 
								 | 
							
														position: absolute;
							 | 
						||
| 
								 | 
							
														top: -5px;
							 | 
						||
| 
								 | 
							
														right: -5px;
							 | 
						||
| 
								 | 
							
														min-width: 16px;
							 | 
						||
| 
								 | 
							
														height: 16px;
							 | 
						||
| 
								 | 
							
														border-radius: 8px;
							 | 
						||
| 
								 | 
							
														background-color: #ff5252;
							 | 
						||
| 
								 | 
							
														color: #ffffff;
							 | 
						||
| 
								 | 
							
														font-size: 10px;
							 | 
						||
| 
								 | 
							
														line-height: 16px;
							 | 
						||
| 
								 | 
							
														text-align: center;
							 | 
						||
| 
								 | 
							
														padding: 0 4px;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												.tab-text {
							 | 
						||
| 
								 | 
							
													font-size: 12px;
							 | 
						||
| 
								 | 
							
													color: #999999;
							 | 
						||
| 
								 | 
							
													line-height: 1.2;
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
													&.active {
							 | 
						||
| 
								 | 
							
														color: #2979FF;
							 | 
						||
| 
								 | 
							
														font-weight: 500;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												.active-indicator {
							 | 
						||
| 
								 | 
							
													position: absolute;
							 | 
						||
| 
								 | 
							
													bottom: -8px;
							 | 
						||
| 
								 | 
							
													left: 50%;
							 | 
						||
| 
								 | 
							
													transform: translateX(-50%);
							 | 
						||
| 
								 | 
							
													width: 16px;
							 | 
						||
| 
								 | 
							
													height: 3px;
							 | 
						||
| 
								 | 
							
													background-color: #2979FF;
							 | 
						||
| 
								 | 
							
													border-radius: 3px;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								</style> 
							 |