uniapp(2)自定义tabbar

创建tabbar

1、系统用的tabbar

"tabBar": {
		"selectedColor": "#00b5ff",//选中的文字颜色
		"fontSize": "20rpx",//字体大小
		"height": "130rpx",//高度
		"list": [
			{
				"pagePath":"pages/home/home",
				"text": "首页",
				"selectedIconPath": "static/ic_home_col.png",//选中的图标样式
				"iconPath": "static/ic_home_gray.png"
				
			},
			{
				"pagePath":"pages/mission/mission",
				"text": "任务广场",
				"iconPath": "static/ic_guangchang_gray.png",
				"selectedIconPath": "static/ic_guangchang_col.png"
				
			},
			{
				"pagePath": "pages/myMission/myMission",
				"text": "我的任务",
				"iconPath": "static/ic_task_gray.png",
				"selectedIconPath": "static/ic_task_col.png"
				
			},{
				"pagePath": "pages/my/my",
				"text": "我的",
				"selectedIconPath": "static/ic_mine_col.png",
				"iconPath": "static/ic_mine_gray.png"
				
			}
		]
	}

2、使用组件tabbar或者自定义tabbar

这里使用uView的自定义tabbar

在需求中,有点击选中未选中icon的样式大小,文字大小还有tabbar的高度问题,

利用view在tabbar外包一层,设置需要的高度,颜色设置成组件一致颜色

利用slot进行独立配置是否激活状态

<view class="bottomBar">
		<u-tabbar :value="value" @change="name => value = name" 
:fixed="fase" :placeholder="true"
			activeColor="#00adff" 
:safeAreaInsetBottom="false">
			<u-tabbar-item text="首页">
				<view class="push_icon" slot="active-icon">
				<u-image src="/static/ic_home_col.png" 
width="16px" height="16px">
</u-image>
				</view>
				<view slot="inactive-icon">
					<u-image src="/static/ic_home_gray.png"
 width="16px" height="16px">
</u-image>
				</view>
				</u-tabbar-item>
				<u-tabbar-item text="任务广场"></u-tabbar-item>
				<u-tabbar-item text="我的任务"></u-tabbar-item>
				<u-tabbar-item text="个人中心"></u-tabbar-item>
			</u-tabbar>
	</view>

调用@change="name => value = name"为你配置的value值

使用<u-tabbar-item text="首页" @click="clicktabbar">事件进行点击匹配跳转

<think>我们正在讨论UniApp中如何实现自定义底部导航栏(TabBar)。根据用户的问题和提供的引用,我们可以总结出以下关键点: 1. **隐藏原生TabBar**:在非微信小程序平台(如H5、App等),需要使用`uni.hideTabBar()`方法隐藏原生TabBar。在微信小程序中,只需在`pages.json`中配置`"custom": true`即可。 2. **创建自定义组件**:创建一个自定义组件(如`Tabbar.vue`)作为底部导航栏。 3. **页面引入自定义TabBar**:在每个页面中引入自定义TabBar组件,并放置在页面底部。 4. **状态管理**:通过Vue的响应式状态(如`currentPage`)来管理当前选中的页面,并通过事件(如`change`)来切换页面。 5. **解决首次闪烁问题**:引用[2]中提到通过`v-if`和页面状态数组来控制页面的显示,可能用于解决页面切换时的闪烁问题。 接下来,我们逐步说明如何实现自定义TabBar。 ### 步骤1:配置pages.json 在`pages.json`中,我们需要设置`tabBar`的`custom`属性为`true`,这样在微信小程序中就会隐藏原生TabBar。同时,我们需要配置`pages`数组和`tabBar`的`list`,但注意`custom`为true时,`list`不会生效,但配置了也不会报错,所以可以保留作为参考。 ```json { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }, // 其他页面 ], "tabBar": { "custom": true, "list": [ { "pagePath": "pages/index/index", "text": "首页" }, // 其他tab页 ] } } ``` ### 步骤2:创建自定义TabBar组件 在项目中创建一个组件,例如`/components/Tabbar/Tabbar.vue`。 在这个组件中,我们将设计底部导航栏的布局和样式,包括中间凸起的按钮。同时,我们需要通过`props`接收当前页面标识,并通过`emit`事件通知父组件切换页面。 **Tabbar.vue**: ```vue <template> <view class="custom-tabbar"> <view v-for="(item, index) in list" :key="index" class="tabbar-item" :class="{ 'active': currentItem === index }" @click="switchTab(index, item.pagePath)"> <!-- 中间凸起的按钮特殊处理 --> <view v-if="item.midButton" class="mid-button"> <!-- 这里可以放置一个特殊的图标 --> </view> <view v-else> <image :src="currentItem === index ? item.selectedIconPath : item.iconPath" class="icon"></image> <text>{{ item.text }}</text> </view> </view> </view> </template> <script setup> import { ref } from 'vue'; const props = defineProps({ currentPage: { type: Number, default: 0 } }); const emit = defineEmits(['change']); // 当前选中的项,初始化为props.currentPage const currentItem = ref(props.currentPage); // 导航栏数据 const list = ref([ { pagePath: "/pages/index/index", text: "首页", iconPath: "/static/tabbar/home.png", selectedIconPath: "/static/tabbar/home_active.png" }, { pagePath: "/pages/mid/mid", // 中间按钮对应的页面,也可以是一个操作(比如弹出模态框) text: "", midButton: true }, { pagePath: "/pages/user/user", text: "我的", iconPath: "/static/tabbar/user.png", selectedIconPath: "/static/tabbar/user_active.png" } ]); // 切换Tab function switchTab(index, pagePath) { if (index === currentItem.value) return; currentItem.value = index; emit('change', index); // 跳转页面 uni.switchTab({ url: pagePath }); } </script> <style> .custom-tabbar { position: fixed; bottom: 0; left: 0; right: 0; height: 100rpx; /* 根据实际需求调整 */ display: flex; justify-content: space-around; align-items: center; background: #fff; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1); z-index: 999; } .tabbar-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; } .mid-button { width: 80rpx; height: 80rpx; border-radius: 50%; background: #07c160; position: relative; top: -20rpx; /* 向上凸出 */ } .icon { width: 50rpx; height: 50rpx; } .active { color: #07c160; } </style> ``` ### 步骤3:在页面中引入自定义TabBar 在每个需要底部导航栏的页面中引入自定义TabBar组件。注意,这些页面应该是`tabBar`配置中对应的页面,并且使用`uni.switchTab`进行跳转。 **示例页面(/pages/index/index.vue)**: ```vue <template> <view> <!-- 页面内容 --> <scroll-view scroll-y style="height: 100vh;"> <!-- 页面具体内容 --> </scroll-view> <!-- 引入自定义TabBar --> <TabBar :currentPage="0" @change="handleTabChange" /> </view> </template> <script setup> import TabBar from '@/components/Tabbar/Tabbar.vue'; // 处理TabBar切换事件 function handleTabChange(index) { // 这里可以做一些切换前的处理 console.log('切换到', index); } </script> ``` ### 步骤4:处理非微信小程序平台隐藏原生TabBar自定义TabBar组件的`onMounted`生命周期中,我们需要隐藏原生TabBar(非微信小程序平台)。 在`Tabbar.vue`的`<script setup>`中添加: ```vue <script setup> import { onMounted } from 'vue'; onMounted(() => { // 非微信小程序平台隐藏原生TabBar if (process.env.VUE_APP_PLATFORM !== 'mp-weixin') { uni.hideTabBar(); } }); </script> ``` ### 步骤5:解决首次闪烁问题(可选) 引用[2]中提到使用`v-if`和页面状态数组来控制页面显示,以避免首次加载时的闪烁。具体做法是在父组件(页面组件)中维护一个页面状态数组,初始只显示当前页面,其他页面隐藏,当切换时再显示其他页面。 在页面组件中: ```vue <template> <view> <view v-if="pageStatus[0]" class="page__container"> <!-- 首页内容 --> </view> <view v-if="pageStatus[1]" class="page__container"> <!-- 第二个页面内容 --> </view> <view v-if="pageStatus[2]" class="page__container"> <!-- 第三个页面内容 --> </view> <TabBar :current-page="currentPage" @change="changePage" /> </view> </template> <script setup> import { ref } from 'vue'; const currentPage = ref(0); const pageStatus = ref([true, false, false]); // 初始只显示第一个页面 function changePage(index) { // 隐藏当前页面,显示目标页面 pageStatus.value[currentPage.value] = false; currentPage.value = index; pageStatus.value[index] = true; } </script> ``` ### 注意事项 1. **页面跳转**:使用`uni.switchTab`跳转时,目标页面必须是在`pages.json`中`tabBar`的`list`里配置的页面(即使我们自定义TabBar,这个配置也是必须的,因为`switchTab`需要知道哪些页面是tab页)。 2. **中间凸起按钮**:如果中间按钮不需要跳转页面(比如只是弹出一个模态框),则可以在`switchTab`方法中做特殊处理,不执行跳转,而是执行其他操作。 3. **样式调整**:凸起按钮的样式可能需要根据具体设计调整,比如大小、位置等。 通过以上步骤,我们就可以在UniApp中实现自定义底部导航栏,包括中间凸起的效果。 §§相关问题§§ 1. 如何在UniApp中隐藏原生TabBar2. 自定义TabBar组件如何与页面进行通信(如切换页面)? 3. 如何解决自定义TabBar在页面切换时的闪烁问题? 4. 在自定义TabBar中,如何实现中间凸起的按钮样式?</think>在 UniApp 中实现自定义底部导航栏(TabBar)的步骤如下,结合引用内容和最佳实践: ### 实现步骤 1. **配置 pages.json** ```json { "tabBar": { "custom": true, // 启用自定义TabBar "list": [ // 仍需配置页面路径 {"pagePath": "pages/index/index", "text": "首页"}, {"pagePath": "pages/mid/mid", "text": ""}, // 中间凸起项 {"pagePath": "pages/user/user", "text": "我的"} ] } } ``` 2. **创建自定义组件** ```vue <!-- components/Tabbar.vue --> <template> <view class="custom-tabbar"> <!-- 左侧按钮 --> <view @click="switchTab(0)" class="tab-item"> <image :src="currentItem === 0 ? '/static/home_active.png' : '/static/home.png'"/> <text>首页</text> </view> <!-- 中间凸起按钮 --> <view class="mid-button" @click="switchTab(1)"> <image src="/static/mid_icon.png"/> </view> <!-- 右侧按钮 --> <view @click="switchTab(2)" class="tab-item"> <image :src="currentItem === 2 ? '/static/user_active.png' : '/static/user.png'"/> <text>我的</text> </view> </view> </template> <script setup> import { ref } from 'vue' const props = defineProps(['currentPage']) const currentItem = ref(props.currentPage) const emit = defineEmits(['change']) // 切换标签页 const switchTab = (index) => { currentItem.value = index emit('change', index) uni.switchTab({ url: getPagePath(index) }) } // 获取对应页面路径 const getPagePath = (index) => { const pages = ['/pages/index/index', '/pages/mid/mid', '/pages/user/user'] return pages[index] } // 隐藏原生TabBar(非微信小程序) onMounted(() => { if (process.env.VUE_APP_PLATFORM !== 'mp-weixin') { uni.hideTabBar() } }) </script> <style> .custom-tabbar { position: fixed; bottom: 0; display: flex; width: 100%; height: 100rpx; background: white; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1); } .mid-button { width: 120rpx; height: 120rpx; border-radius: 50%; background: #07c160; position: relative; top: -40rpx; /* 实现凸起效果 */ } </style> ``` 3. **在页面中使用** ```vue <!-- pages/index/index.vue --> <template> <view> <!-- 页面内容 --> <scroll-view scroll-y style="height: 100vh;"> ... </scroll-view> <!-- 引入自定义TabBar --> <TabBar :currentPage="0" @change="handleTabChange"/> </view> </template> <script setup> import TabBar from '@/components/Tabbar.vue' // 处理TabBar切换 const handleTabChange = (index) => { console.log('切换到标签页:', index) } </script> ``` ### 关键点说明 1. **隐藏原生TabBar**: - 微信小程序:通过 `"custom": true` 配置自动隐藏[^1] - 其他平台:使用 `uni.hideTabBar()` 手动隐藏[^1] 2. **凸起效果实现**: - 使用 `position: relative` + `top: -40rpx` 使按钮上移 - 添加圆形背景和阴影增强视觉效果 3. **状态管理**: - 通过 `currentPage` 属性传递当前激活项 - 使用 `@change` 事件处理页面切换 4. **解决闪烁问题**: - 在页面容器使用 `v-if` 控制显示[^2] - 避免同时加载所有页面内容 ### 注意事项 1. **页面路径配置**:即使自定义 TabBar,仍需在 `pages.json` 配置 `tabBar.list` 2. **平台差异**:H5 和 App 平台需手动调用 `hideTabBar()` 3. **位置计算**:凸起按钮高度需考虑安全区域(iPhoneX 等全面屏设备) 4. **性能优化**:使用 `v-if` 替代 `v-show` 避免初始化加载所有页面[^2] > 提示:中间凸起按钮通常对应特殊功能(如扫码、发布),可直接跳转页面或触发模态框
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值