hi,小伙伴们,我们在使用不同app或者小程序的时候发现底部导航栏各式各样,每个都有自己的特点,我们今天也自定义一版底部导航栏,废话不多说,直接上代码!
template模块
<template>
<view class="tab-bar">
<view class="tabbar-container">
<view class="tabbar-item" v-for="(item, index) in tabBarList"
:class="[item.isCenter ? 'center' : '']"
@click="handleChange(item)">
<view class="item-top">
<image :src="currentPath == item.path ? item.selectIcon : item.icon"></image>
</view>
<view class="item-bottom" :class="[currentPath == item.path ? 'item-active' : '']">
<text>{{ item.text }}</text>
</view>
</view>
</view>
</view>
</template>
js模块
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { ref } from 'vue'
import { tabBarList } from './data' //看下面data模块
/**
* 参数名 类型 描述
* currentPath String 当前页面路径
*/
const props = defineProps({
currentPath: {
type: String,
default: () => '/pages/index/index'
},
})
const emit = defineEmits(["scroll-height"])
const currentPath = ref(`/${props.currentPath}`)
const scrollHeight = ref(0)
const handleChange = (item) => {
uni.switchTab({ url: item.path })
}
onLoad(() => {
//隐藏原生tabbar
uni.hideTabBar();
//以下代码为了列表触底加载使用,按照个人需求(可删除/可自定义)
uni.getSystemInfo({
success: (res)=>{
let info = uni.createSelectorQuery().select(".tab-bar");
info.boundingClientRect((data)=>{
scrollHeight.value = res.screenHeight - data.height - res.statusBarHeight - 100;
emit("scroll-height", scrollHeight.value)
}).exec()
}
});
});
</script>
style模块
<style lang="scss">
view {
padding: 0;
margin: 0;
box-sizing: border-box;
z-index: 999;
}
.tabbar-container {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 120rpx;
display: flex;
align-items: center;
padding: 5rpx 0;
color: #999999;
background-color: #ffffff;
.tabbar-item {
height: 100rpx;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
text-align: center;
margin-bottom: 30rpx;
.item-top {
width: 70rpx;
height: 70rpx;
padding: 10rpx;
image {
width: 100%;
height: 100%;
}
}
.item-bottom {
font-size: 24rpx;
width: 100%;
}
}
.item-active {
color: $uni-bg-color;
}
.center {
display: block;
position: relative;
.item-top {
flex-shrink: 0;
width: 100rpx;
height: 100rpx;
position: absolute;
top: -40rpx;
left: calc(50% - 50rpx);
border-radius: 50%;
box-shadow: 0 0 5px #999;
background-color: #ffffff;
}
.item-bottom {
position: absolute;
bottom: 5rpx;
}
}
}
</style>
data模块
export const tabBarList = [
{
index: 0,
path: '/pages/index/index',
icon: '/static/c1.png',
selectIcon: '/static/c2.png',
text: '首页',
isCenter: false
},
{
index: 1,
path: '/pages/order/index',
icon: '/static/c3.png',
selectIcon: '/static/c4.png',
text: '订单',
isCenter: false
},
{
index: 2,
path: '/pages/mine/index',
icon: '/static/c5.png',
selectIcon: '/static/c6.png',
text: '我的',
isCenter: false
},
]
tabBar父组件使用(顺带封装一个页面公共容器组件 scroll-view.vue)
<template>
<view class="container">
<!-- 页面内容 -->
<view class="content">
<slot name="content"/>
</view>
<!-- 自定义底部导航栏 -->
<view class="tab-bar">
<slot name="footer"/>
<my-tab-bar
v-if="props.showBar"
:current-path="currentPath"
@scroll-height="getScrollHeight"
></my-tab-bar>
</view>
</view>
</template>
<script setup>
import { reactive, ref, computed } from 'vue'
import myTabBar from 'tabbar组件存放路径'
/**
* 参数名称 类型 描述
* showBar Boolean 是否展示底部导航栏
*/
const props = defineProps({
showBar: {
type: Boolean,
default: () => true
}
})
const emit = defineEmits(['scroll-height'])
const routes = getCurrentPages()
const currentPath = routes[routes.length - 1].route
const getScrollHeight = (val) => {
emit('scroll-height', val)
}
</script>
<style lang="scss">
.container {
height: 100vh;
display: flex;
flex-direction: column;
background-color: $uni-bg-color;
.content {
flex: 1;
}
}
</style>
具体页面使用
<template>
<my-scroll-view>
<template slot="content">
<view class="nav"> {{ title }} </view>
</template>
<template slot="footer">
<!-- 自定义底部导航栏 -->
<!-- 类名需要和tabbar组件uni.createSelectorQuery().select(".tab-bar")这步保持一致 -->
<view class="tab-bar"></view>
</template>
</my-scroll-view>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import myScrollView from 'scroll-view组件存放位置'
const title = ref('订单')
</script>
<style lang="scss"></style>
data模块 isCenter 设置为true效果如下:
data模块 isCenter 设置为false效果如下:
以上就是简单实现了一版自定义导航效果,具体看个人需求修改。