hookehuyr

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

移除原生tabbar配置,新增自定义TabBar组件并在各页面引入
......@@ -8,7 +8,6 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
NavBar: typeof import('./src/components/navBar.vue')['default']
NutConfigProvider: typeof import('@nutui/nutui-taro')['ConfigProvider']
NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar']
NutSwiper: typeof import('@nutui/nutui-taro')['Swiper']
NutSwiperItem: typeof import('@nutui/nutui-taro')['SwiperItem']
......@@ -16,5 +15,6 @@ declare module 'vue' {
PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TabBar: typeof import('./src/components/TabBar.vue')['default']
}
}
......
......@@ -26,42 +26,5 @@ export default {
navigationBarTitleText: 'WeChat',
navigationBarTextStyle: 'black'
},
tabBar: {
color: '#6b7280',
selectedColor: '#f97316',
backgroundColor: '#ffffff',
borderStyle: 'black',
list: [
{
pagePath: 'pages/index/index',
text: '首页',
iconPath: 'assets/images/icon/icon_home1@2x.png',
selectedIconPath: 'assets/images/icon/icon_home2@2x.png'
},
{
pagePath: 'pages/post/index',
text: '分类',
iconPath: 'assets/images/icon/icon_book1@2x.png',
selectedIconPath: 'assets/images/icon/icon_book2@2x.png'
},
{
pagePath: 'pages/sell/index',
text: '我要卖车',
iconPath: 'assets/images/icon/icon_server1.png',
selectedIconPath: 'assets/images/icon/icon_server2.png'
},
{
pagePath: 'pages/messages/index',
text: '消息',
iconPath: 'assets/images/icon/icon_book1@2x.png',
selectedIconPath: 'assets/images/icon/icon_book2@2x.png'
},
{
pagePath: 'pages/profile/index',
text: '我的',
iconPath: 'assets/images/icon/icon_my1@2x.png',
selectedIconPath: 'assets/images/icon/icon_my2@2x.png'
}
]
}
}
......
<template>
<div class="fixed bottom-0 w-full max-w-md mx-auto z-50">
<div class="backdrop-blur-md bg-white/70 border-t border-gray-200 px-4 py-2">
<div class="flex justify-around items-center">
<!-- 首页 -->
<view
@click="navigateTo('/pages/index/index')"
:class="getTabClass('index')"
>
<Home size="20" :color="getIconColor('index')" />
<span class="text-xs mt-1">首页</span>
</view>
<!-- 分类 -->
<view
@click="navigateTo('/pages/post/index')"
:class="getTabClass('post')"
>
<Category size="20" :color="getIconColor('post')" />
<span class="text-xs mt-1">分类</span>
</view>
<!-- 我要卖车 -->
<div class="relative -mt-5">
<view
@click="navigateTo('/pages/sell/index')"
class="bg-orange-500 rounded-full p-3 text-white shadow-lg"
>
<span class="text-sm font-medium">我要卖车</span>
</view>
</div>
<!-- 消息 -->
<view
@click="navigateTo('/pages/messages/index')"
:class="getTabClass('messages')"
>
<Comment size="20" :color="getIconColor('messages')" />
<span class="text-xs mt-1">消息</span>
</view>
<!-- 我的 -->
<view
@click="navigateTo('/pages/profile/index')"
:class="getTabClass('profile')"
>
<My size="20" :color="getIconColor('profile')" />
<span class="text-xs mt-1">我的</span>
</view>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { Home, Category, Comment, My } from '@nutui/icons-vue-taro'
// 当前激活的tab
const activeTab = ref('')
/**
* 获取当前页面路径并设置激活状态
*/
const getCurrentPage = () => {
const pages = Taro.getCurrentPages()
if (pages.length > 0) {
const currentPage = pages[pages.length - 1]
const route = currentPage.route
if (route.includes('index/index')) {
activeTab.value = 'index'
} else if (route.includes('post/index')) {
activeTab.value = 'post'
} else if (route.includes('sell/index')) {
activeTab.value = 'sell'
} else if (route.includes('messages/index')) {
activeTab.value = 'messages'
} else if (route.includes('profile/index')) {
activeTab.value = 'profile'
}
}
}
/**
* 导航到指定页面
* @param {string} url - 页面路径
*/
const navigateTo = (url) => {
Taro.redirectTo({
url: url
})
}
/**
* 获取tab按钮的样式类
* @param {string} tab - tab标识
* @returns {string} 样式类名
*/
const getTabClass = (tab) => {
const baseClass = 'flex flex-col items-center p-2'
const activeClass = activeTab.value === tab ? 'text-orange-500' : 'text-gray-500'
return `${baseClass} ${activeClass}`
}
/**
* 获取图标颜色
* @param {string} tab - tab标识
* @returns {string} 颜色值
*/
const getIconColor = (tab) => {
return activeTab.value === tab ? '#f97316' : '#6b7280'
}
onMounted(() => {
getCurrentPage()
})
</script>
<style lang="less" scoped>
/* 确保底部导航栏在最上层 */
.z-50 {
z-index: 50;
}
</style>
<!--
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-01 21:32:07
* @LastEditTime: 2025-07-01 21:50:54
* @FilePath: /jgdl/src/pages/index/index.vue
* @Description: 捡个电驴首页
-->
......@@ -143,6 +143,9 @@
</view>
</view>
</view>
<!-- 自定义TabBar -->
<TabBar />
</view>
</template>
......@@ -151,7 +154,8 @@ import Taro from '@tarojs/taro'
// import '@tarojs/taro/html.css' 和 nutui组件居然有冲突?
import { ref, onMounted } from 'vue'
import { useDidShow, useReady } from '@tarojs/taro'
import { Clock, Star, Service, Right, Heart1, Addfollow, HeartFill, Check, Search2, Shop } from '@nutui/icons-vue-taro'
import { Clock, Star, Right, Addfollow, HeartFill, Check, Search2, Shop } from '@nutui/icons-vue-taro'
import TabBar from '@/components/TabBar.vue'
import "./index.less";
// 响应式数据
......
......@@ -58,13 +58,17 @@
<view class="floating-btn" @click="onNewMessage">
<Plus size="24" color="#ffffff" />
</view>
<!-- 自定义TabBar -->
<TabBar />
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { Search, Message, Plus } from '@nutui/icons-vue-taro'
import { Search, Message, Plus, Image } from '@nutui/icons-vue-taro'
import Taro from '@tarojs/taro'
import TabBar from '@/components/TabBar.vue'
// 响应式数据
const searchValue = ref('')
......
......@@ -100,11 +100,16 @@
</view>
</view>
</view>
<!-- 自定义TabBar -->
<TabBar />
</template>
<script setup>
import { ref } from 'vue'
import Taro from '@tarojs/taro'
import { Search, Right, Cart, Star, Cart2, Category, Heart } from '@nutui/icons-vue-taro'
import TabBar from '@/components/TabBar.vue'
// 响应式数据
const searchValue = ref('')
......@@ -187,18 +192,10 @@ const onProductClick = () => {
})
}
const onSearch = () => {
Taro.showToast({
title: '搜索功能',
icon: 'none'
})
}
/**
* 查看更多点击事件
* @param {string} type - 类型(hot/latest)
*/
const onViewMore = (type) => {
const onViewMore = () => {
// 跳转到列表页面
}
</script>
......
......@@ -120,6 +120,9 @@
<view class="logout-section">
<button class="logout-btn" @click="onLogout">退出登录</button>
</view>
<!-- 自定义TabBar -->
<TabBar />
</view>
</template>
......@@ -130,6 +133,7 @@ import {
Voice, Message, Tips, Setting
} from '@nutui/icons-vue-taro'
import Taro from '@tarojs/taro'
import TabBar from '@/components/TabBar.vue'
// 用户信息
const userInfo = ref({
......
......@@ -176,6 +176,9 @@
<button class="preview-btn" @click="onPreview">预览</button>
<button class="publish-btn" @click="onPublish">发布车辆</button>
</view>
<!-- 自定义TabBar -->
<TabBar />
</view>
</template>
......@@ -183,6 +186,7 @@
import { ref, reactive } from 'vue'
import { Close, Plus, Right } from '@nutui/icons-vue-taro'
import Taro from '@tarojs/taro'
import TabBar from '@/components/TabBar.vue'
// 响应式数据
const vehicleImages = ref([])
......