hookehuyr

feat(tabbar): 添加自定义底部导航栏组件并替换原生tabbar

移除原生tabbar配置,新增自定义TabBar组件并在各页面引入
...@@ -8,7 +8,6 @@ export {} ...@@ -8,7 +8,6 @@ export {}
8 declare module 'vue' { 8 declare module 'vue' {
9 export interface GlobalComponents { 9 export interface GlobalComponents {
10 NavBar: typeof import('./src/components/navBar.vue')['default'] 10 NavBar: typeof import('./src/components/navBar.vue')['default']
11 - NutConfigProvider: typeof import('@nutui/nutui-taro')['ConfigProvider']
12 NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar'] 11 NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar']
13 NutSwiper: typeof import('@nutui/nutui-taro')['Swiper'] 12 NutSwiper: typeof import('@nutui/nutui-taro')['Swiper']
14 NutSwiperItem: typeof import('@nutui/nutui-taro')['SwiperItem'] 13 NutSwiperItem: typeof import('@nutui/nutui-taro')['SwiperItem']
...@@ -16,5 +15,6 @@ declare module 'vue' { ...@@ -16,5 +15,6 @@ declare module 'vue' {
16 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default'] 15 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
17 RouterLink: typeof import('vue-router')['RouterLink'] 16 RouterLink: typeof import('vue-router')['RouterLink']
18 RouterView: typeof import('vue-router')['RouterView'] 17 RouterView: typeof import('vue-router')['RouterView']
18 + TabBar: typeof import('./src/components/TabBar.vue')['default']
19 } 19 }
20 } 20 }
......
...@@ -26,42 +26,5 @@ export default { ...@@ -26,42 +26,5 @@ export default {
26 navigationBarTitleText: 'WeChat', 26 navigationBarTitleText: 'WeChat',
27 navigationBarTextStyle: 'black' 27 navigationBarTextStyle: 'black'
28 }, 28 },
29 - tabBar: { 29 +
30 - color: '#6b7280',
31 - selectedColor: '#f97316',
32 - backgroundColor: '#ffffff',
33 - borderStyle: 'black',
34 - list: [
35 - {
36 - pagePath: 'pages/index/index',
37 - text: '首页',
38 - iconPath: 'assets/images/icon/icon_home1@2x.png',
39 - selectedIconPath: 'assets/images/icon/icon_home2@2x.png'
40 - },
41 - {
42 - pagePath: 'pages/post/index',
43 - text: '分类',
44 - iconPath: 'assets/images/icon/icon_book1@2x.png',
45 - selectedIconPath: 'assets/images/icon/icon_book2@2x.png'
46 - },
47 - {
48 - pagePath: 'pages/sell/index',
49 - text: '我要卖车',
50 - iconPath: 'assets/images/icon/icon_server1.png',
51 - selectedIconPath: 'assets/images/icon/icon_server2.png'
52 - },
53 - {
54 - pagePath: 'pages/messages/index',
55 - text: '消息',
56 - iconPath: 'assets/images/icon/icon_book1@2x.png',
57 - selectedIconPath: 'assets/images/icon/icon_book2@2x.png'
58 - },
59 - {
60 - pagePath: 'pages/profile/index',
61 - text: '我的',
62 - iconPath: 'assets/images/icon/icon_my1@2x.png',
63 - selectedIconPath: 'assets/images/icon/icon_my2@2x.png'
64 - }
65 - ]
66 - }
67 } 30 }
......
1 +<template>
2 + <div class="fixed bottom-0 w-full max-w-md mx-auto z-50">
3 + <div class="backdrop-blur-md bg-white/70 border-t border-gray-200 px-4 py-2">
4 + <div class="flex justify-around items-center">
5 + <!-- 首页 -->
6 + <view
7 + @click="navigateTo('/pages/index/index')"
8 + :class="getTabClass('index')"
9 + >
10 + <Home size="20" :color="getIconColor('index')" />
11 + <span class="text-xs mt-1">首页</span>
12 + </view>
13 +
14 + <!-- 分类 -->
15 + <view
16 + @click="navigateTo('/pages/post/index')"
17 + :class="getTabClass('post')"
18 + >
19 + <Category size="20" :color="getIconColor('post')" />
20 + <span class="text-xs mt-1">分类</span>
21 + </view>
22 +
23 + <!-- 我要卖车 -->
24 + <div class="relative -mt-5">
25 + <view
26 + @click="navigateTo('/pages/sell/index')"
27 + class="bg-orange-500 rounded-full p-3 text-white shadow-lg"
28 + >
29 + <span class="text-sm font-medium">我要卖车</span>
30 + </view>
31 + </div>
32 +
33 + <!-- 消息 -->
34 + <view
35 + @click="navigateTo('/pages/messages/index')"
36 + :class="getTabClass('messages')"
37 + >
38 + <Comment size="20" :color="getIconColor('messages')" />
39 + <span class="text-xs mt-1">消息</span>
40 + </view>
41 +
42 + <!-- 我的 -->
43 + <view
44 + @click="navigateTo('/pages/profile/index')"
45 + :class="getTabClass('profile')"
46 + >
47 + <My size="20" :color="getIconColor('profile')" />
48 + <span class="text-xs mt-1">我的</span>
49 + </view>
50 + </div>
51 + </div>
52 + </div>
53 +</template>
54 +
55 +<script setup>
56 +import { ref, onMounted } from 'vue'
57 +import Taro from '@tarojs/taro'
58 +import { Home, Category, Comment, My } from '@nutui/icons-vue-taro'
59 +
60 +// 当前激活的tab
61 +const activeTab = ref('')
62 +
63 +/**
64 + * 获取当前页面路径并设置激活状态
65 + */
66 +const getCurrentPage = () => {
67 + const pages = Taro.getCurrentPages()
68 + if (pages.length > 0) {
69 + const currentPage = pages[pages.length - 1]
70 + const route = currentPage.route
71 +
72 + if (route.includes('index/index')) {
73 + activeTab.value = 'index'
74 + } else if (route.includes('post/index')) {
75 + activeTab.value = 'post'
76 + } else if (route.includes('sell/index')) {
77 + activeTab.value = 'sell'
78 + } else if (route.includes('messages/index')) {
79 + activeTab.value = 'messages'
80 + } else if (route.includes('profile/index')) {
81 + activeTab.value = 'profile'
82 + }
83 + }
84 +}
85 +
86 +/**
87 + * 导航到指定页面
88 + * @param {string} url - 页面路径
89 + */
90 +const navigateTo = (url) => {
91 + Taro.redirectTo({
92 + url: url
93 + })
94 +}
95 +
96 +/**
97 + * 获取tab按钮的样式类
98 + * @param {string} tab - tab标识
99 + * @returns {string} 样式类名
100 + */
101 +const getTabClass = (tab) => {
102 + const baseClass = 'flex flex-col items-center p-2'
103 + const activeClass = activeTab.value === tab ? 'text-orange-500' : 'text-gray-500'
104 + return `${baseClass} ${activeClass}`
105 +}
106 +
107 +/**
108 + * 获取图标颜色
109 + * @param {string} tab - tab标识
110 + * @returns {string} 颜色值
111 + */
112 +const getIconColor = (tab) => {
113 + return activeTab.value === tab ? '#f97316' : '#6b7280'
114 +}
115 +
116 +onMounted(() => {
117 + getCurrentPage()
118 +})
119 +</script>
120 +
121 +<style lang="less" scoped>
122 +/* 确保底部导航栏在最上层 */
123 +.z-50 {
124 + z-index: 50;
125 +}
126 +</style>
1 <!-- 1 <!--
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-01 21:32:07 4 + * @LastEditTime: 2025-07-01 21:50:54
5 * @FilePath: /jgdl/src/pages/index/index.vue 5 * @FilePath: /jgdl/src/pages/index/index.vue
6 * @Description: 捡个电驴首页 6 * @Description: 捡个电驴首页
7 --> 7 -->
...@@ -143,6 +143,9 @@ ...@@ -143,6 +143,9 @@
143 </view> 143 </view>
144 </view> 144 </view>
145 </view> 145 </view>
146 +
147 + <!-- 自定义TabBar -->
148 + <TabBar />
146 </view> 149 </view>
147 </template> 150 </template>
148 151
...@@ -151,7 +154,8 @@ import Taro from '@tarojs/taro' ...@@ -151,7 +154,8 @@ import Taro from '@tarojs/taro'
151 // import '@tarojs/taro/html.css' 和 nutui组件居然有冲突? 154 // import '@tarojs/taro/html.css' 和 nutui组件居然有冲突?
152 import { ref, onMounted } from 'vue' 155 import { ref, onMounted } from 'vue'
153 import { useDidShow, useReady } from '@tarojs/taro' 156 import { useDidShow, useReady } from '@tarojs/taro'
154 -import { Clock, Star, Service, Right, Heart1, Addfollow, HeartFill, Check, Search2, Shop } from '@nutui/icons-vue-taro' 157 +import { Clock, Star, Right, Addfollow, HeartFill, Check, Search2, Shop } from '@nutui/icons-vue-taro'
158 +import TabBar from '@/components/TabBar.vue'
155 import "./index.less"; 159 import "./index.less";
156 160
157 // 响应式数据 161 // 响应式数据
......
...@@ -58,13 +58,17 @@ ...@@ -58,13 +58,17 @@
58 <view class="floating-btn" @click="onNewMessage"> 58 <view class="floating-btn" @click="onNewMessage">
59 <Plus size="24" color="#ffffff" /> 59 <Plus size="24" color="#ffffff" />
60 </view> 60 </view>
61 +
62 + <!-- 自定义TabBar -->
63 + <TabBar />
61 </view> 64 </view>
62 </template> 65 </template>
63 66
64 <script setup> 67 <script setup>
65 import { ref, computed } from 'vue' 68 import { ref, computed } from 'vue'
66 -import { Search, Message, Plus } from '@nutui/icons-vue-taro' 69 +import { Search, Message, Plus, Image } from '@nutui/icons-vue-taro'
67 import Taro from '@tarojs/taro' 70 import Taro from '@tarojs/taro'
71 +import TabBar from '@/components/TabBar.vue'
68 72
69 // 响应式数据 73 // 响应式数据
70 const searchValue = ref('') 74 const searchValue = ref('')
......
...@@ -100,11 +100,16 @@ ...@@ -100,11 +100,16 @@
100 </view> 100 </view>
101 </view> 101 </view>
102 </view> 102 </view>
103 +
104 + <!-- 自定义TabBar -->
105 + <TabBar />
103 </template> 106 </template>
104 107
105 <script setup> 108 <script setup>
106 import { ref } from 'vue' 109 import { ref } from 'vue'
110 +import Taro from '@tarojs/taro'
107 import { Search, Right, Cart, Star, Cart2, Category, Heart } from '@nutui/icons-vue-taro' 111 import { Search, Right, Cart, Star, Cart2, Category, Heart } from '@nutui/icons-vue-taro'
112 +import TabBar from '@/components/TabBar.vue'
108 113
109 // 响应式数据 114 // 响应式数据
110 const searchValue = ref('') 115 const searchValue = ref('')
...@@ -187,18 +192,10 @@ const onProductClick = () => { ...@@ -187,18 +192,10 @@ const onProductClick = () => {
187 }) 192 })
188 } 193 }
189 194
190 -const onSearch = () => {
191 - Taro.showToast({
192 - title: '搜索功能',
193 - icon: 'none'
194 - })
195 -}
196 -
197 /** 195 /**
198 * 查看更多点击事件 196 * 查看更多点击事件
199 - * @param {string} type - 类型(hot/latest)
200 */ 197 */
201 -const onViewMore = (type) => { 198 +const onViewMore = () => {
202 // 跳转到列表页面 199 // 跳转到列表页面
203 } 200 }
204 </script> 201 </script>
......
...@@ -120,6 +120,9 @@ ...@@ -120,6 +120,9 @@
120 <view class="logout-section"> 120 <view class="logout-section">
121 <button class="logout-btn" @click="onLogout">退出登录</button> 121 <button class="logout-btn" @click="onLogout">退出登录</button>
122 </view> 122 </view>
123 +
124 + <!-- 自定义TabBar -->
125 + <TabBar />
123 </view> 126 </view>
124 </template> 127 </template>
125 128
...@@ -130,6 +133,7 @@ import { ...@@ -130,6 +133,7 @@ import {
130 Voice, Message, Tips, Setting 133 Voice, Message, Tips, Setting
131 } from '@nutui/icons-vue-taro' 134 } from '@nutui/icons-vue-taro'
132 import Taro from '@tarojs/taro' 135 import Taro from '@tarojs/taro'
136 +import TabBar from '@/components/TabBar.vue'
133 137
134 // 用户信息 138 // 用户信息
135 const userInfo = ref({ 139 const userInfo = ref({
......
...@@ -176,6 +176,9 @@ ...@@ -176,6 +176,9 @@
176 <button class="preview-btn" @click="onPreview">预览</button> 176 <button class="preview-btn" @click="onPreview">预览</button>
177 <button class="publish-btn" @click="onPublish">发布车辆</button> 177 <button class="publish-btn" @click="onPublish">发布车辆</button>
178 </view> 178 </view>
179 +
180 + <!-- 自定义TabBar -->
181 + <TabBar />
179 </view> 182 </view>
180 </template> 183 </template>
181 184
...@@ -183,6 +186,7 @@ ...@@ -183,6 +186,7 @@
183 import { ref, reactive } from 'vue' 186 import { ref, reactive } from 'vue'
184 import { Close, Plus, Right } from '@nutui/icons-vue-taro' 187 import { Close, Plus, Right } from '@nutui/icons-vue-taro'
185 import Taro from '@tarojs/taro' 188 import Taro from '@tarojs/taro'
189 +import TabBar from '@/components/TabBar.vue'
186 190
187 // 响应式数据 191 // 响应式数据
188 const vehicleImages = ref([]) 192 const vehicleImages = ref([])
......