2***@qq.com
2***@qq.com
  • 发布:2019-12-30 15:18
  • 更新:2024-01-11 14:22
  • 阅读:12948

自定义tabbar,支持H5,app,微信小程序中间凸起,支持uni.switchTab()跳转

分类:uni-app

浏览了很多关于uniapp的自定义tabbar的文章,很多感觉都写的不详细,而且跨端能力都不怎么样,我自己研究整理了一下:

跨端支持:H5、app、微信小程序,

H5效果图如下:



微信小程序效果图如下:

app的效果图没有截取到,但应该是可行的。

目录结构如下:

page.json的配置如下:

{  
    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages  
        {  
            "path": "pages/index/index",  
            "style": {  
                "navigationBarTitleText": "首页"  
            }  
        },{  
            "path": "pages/dynamic/dynamic",  
            "style": {  
                "navigationBarTitleText": "发现"  
            }  
        },{  
            "path": "pages/release/release",  
            "style": {  
                "navigationBarTitleText": "发布"  
            }  
        },{  
            "path": "pages/friend/friend",  
            "style": {  
                "navigationBarTitleText": "朋友"  
            }  
        },{  
            "path": "pages/mine/mine",  
            "style": {  
                "navigationBarTitleText": "我的"  
            }  
        }  
    ],  
    "globalStyle": {  
        "navigationBarTextStyle": "black",  
        "navigationBarTitleText": "uni-app",  
        "navigationBarBackgroundColor": "#F8F8F8",  
        "backgroundColor": "#F8F8F8"  
    },  
    "tabBar": {  
        "color": "#999999",  
        "selectedColor": "#66CCFF",  
        "borderStyle": "black",  
        "backgroundColor": "#ffffff",  
        "midButton": {  
            "text": "发布",  
            "pagePath": "pages/release/release",  
            "iconPath": "static/images/tabbar/release.png",  
            "selectedIconPath": "static/images/tabbar/release-select.png"  
        },  
        "list": [{  
            "pagePath": "pages/index/index",  
            "iconPath": "static/images/tabbar/index.png",  
            "selectedIconPath": "static/images/tabbar/index-select.png",  
            "text": "首页"  
        },{  
            "pagePath": "pages/dynamic/dynamic",  
            "iconPath": "static/images/tabbar/dynamic.png",  
            "selectedIconPath": "static/images/tabbar/dynamic-select.png",  
            "text": "发现"  
        },  
        // #ifndef APP-PLUS  
        {  
            "pagePath": "pages/release/release",  
            "iconPath": "static/images/tabbar/release.png",  
            "selectedIconPath": "static/images/tabbar/release-select.png",  
            "text": "发布"  
        },  
        // #endif  
        {  
            "pagePath": "pages/friend/friend",  
            "iconPath": "static/images/tabbar/friend.png",  
            "selectedIconPath": "static/images/tabbar/friend-select.png",  
            "text": "朋友"  
        },{  
            "pagePath": "pages/mine/mine",  
            "iconPath": "static/images/tabbar/mine.png",  
            "selectedIconPath": "static/images/tabbar/mine-select.png",  
            "text": "我的"  
        }]  
    }  
}  

注册全局组件tabbar在main.js文件中,配置如下:

import Vue from 'vue'  
import App from './App'  
import rwjTabbar from './components/rwj-tabbar.vue'  

Vue.config.productionTip = false  

//注册全局组件  
Vue.component('rwj-tabbar', rwjTabbar);  
App.mpType = 'app'  

const app = new Vue({  
    ...App  
})  
app.$mount()  


rwj-tabbar.vue文件编写:

<template>  
    <view class="tabbar-container">  
        <block>  
            <view class="tabbar-item" v-for="(item,index) in tabbarList" :class="[item.centerItem ? ' center-item' : '']" @click="changeItem(item)">  
                <view class="item-top">  
                    <image :src="currentItem==item.id?item.selectIcon:item.icon"></image>  
                </view>  
                <view class="item-bottom" :class="[currentItem==item.id ? 'item-active' : '']">  
                    <text>{{item.text}}</text>  
                </view>  
            </view>  
        </block>  

    </view>  
</template>  

<script>  
    export default {  
        props:{  
            currentPage: {  
                type: Number,  
                default: 0  
            }  
        },  
        data() {  
            return {  
                currentItem: 0,  
                tabbarList: [  
                    {  
                        id: 0,  
                        path: "/pages/index/index",  
                        icon: "/static/images/tabbar/index.png",  
                        selectIcon: "/static/images/tabbar/index-select.png",  
                        text: "首页",  
                        centerItem: false  
                    },{  
                        id: 1,  
                        path: "/pages/dynamic/dynamic",  
                        icon: "/static/images/tabbar/dynamic.png",  
                        selectIcon: "/static/images/tabbar/dynamic-select.png",  
                        text: "动态",  
                        centerItem: false  
                    },{  
                        id: 2,  
                        path: "/pages/release/release",  
                        icon: "/static/images/tabbar/release.png",  
                        selectIcon: "/static/images/tabbar/release-select.png",  
                        text: "发布",  
                        centerItem: true  
                    },{  
                        id: 3,  
                        path: "/pages/friend/friend",  
                        icon: "/static/images/tabbar/friend.png",  
                        selectIcon: "/static/images/tabbar/friend-select.png",  
                        text: "朋友",  
                        centerItem: false  
                    },{  
                        id: 4,  
                        path: "/pages/mine/mine",  
                        icon: "/static/images/tabbar/mine.png",  
                        selectIcon: "/static/images/tabbar/mine-select.png",  
                        text: "我的",  
                        centerItem: false  
                    }  
                ]  

            };  
        },  
        mounted(){  
            this.currentItem = this.currentPage;  
            uni.hideTabBar();  
        },  
        methods: {  
            changeItem(item){  
                let _this = this;  
                //_this.currentItem = item.id;  
                uni.switchTab({  
                    url: item.path  
                });  
            }  
        }  
    }  
</script>  
<style>  
        view{  
               padding: 0;  
               margin: 0;  
               box-sizing: border-box;  
        }  
    .tabbar-container{  
        position: fixed;  
        bottom: 0;  
        left: 0;  
        width: 100%;  
        height: 110rpx;  
        box-shadow: 0 0 5px #999;  
        display: flex;  
        align-items: center;  
        padding: 5rpx 0;  
        color: #999999;  
    }  
    .tabbar-container .tabbar-item{  
        width: 20%;  
        height: 100rpx;  
        display: flex;  
        flex-direction: column;  
        justify-content: center;  
        align-items: center;  
        text-align: center;  
    }  
    .tabbar-container .item-active{  
        color: #66CCFF;  
    }  
    .tabbar-container .center-item{  
        display: block;  
        position: relative;  
    }  
    .tabbar-container .tabbar-item .item-top{  
        width: 70rpx;  
        height: 70rpx;  
        padding: 10rpx;  
    }  
    .tabbar-container .center-item .item-top{  
        flex-shrink: 0;  
        width: 100rpx;  
        height: 100rpx;  
        position: absolute;  
        top: -50rpx;  
        left: calc(50% - 50rpx);  
        border-radius: 50%;  
        box-shadow: 0 0 5px #999;  
        background-color: #ffffff;  
    }  
    .tabbar-container .tabbar-item .item-top image{  
        width: 100%;  
        height: 100%;  
    }  
    .tabbar-container .tabbar-item .item-bottom{  
        font-size: 28rpx;  
        width: 100%;  
    }  
    .tabbar-container .center-item .item-bottom{  
        position: absolute;  
        bottom: 5rpx;  
    }  
</style>  

index.vue文件中引入tabbar:

<!-- #ifndef APP-PLUS -->  
        <rwj-tabbar :current-page="0"></rwj-tabbar>  
<!-- #endif -->

补充说明:
由于app端不支持uni.hideTabBar();,所以在app端不需要使用自定义组件,而且app端uniapp原生的就支持中间凸起,所以app是使用的原生的tabbar

5 关注 分享
1***@qq.com 船帆 2***@qq.com 7***@qq.com s***@qq.com

要回复文章请先登录注册

w***@163.com

w***@163.com

凸起的tab和其他的tab频繁切换会卡死么
2024-01-11 14:22
2***@qq.com

2***@qq.com

mark
2023-09-25 16:59
c***@163.com

c***@163.com

回复 2***@qq.com :
不如分享下你的方案,这块确实很多人都很迷茫
2022-11-11 12:17
2***@qq.com

2***@qq.com

回复 c***@163.com :
不要用他的。。
2022-11-11 12:14
c***@163.com

c***@163.com

回复 2***@qq.com :
看那个动图切换的效果
2022-11-11 12:04
2***@qq.com

2***@qq.com

回复 c***@163.com :
你是搞小程序还是app?小程序上没有闪,直接定义在app.js里 你启动小或打开程序,tabBar就已经预渲染完了
2022-11-11 11:47
c***@163.com

c***@163.com

没啥完美的方案,要么闪,要么几个页面聚在一个页面。还有啥好的吗?
2022-11-11 11:41
黑泽布小白

黑泽布小白

回复 余予娱与愚 :
我也想知道, 甲方一直很在意这个闪烁
2022-07-08 10:55
明亮的光带

明亮的光带

回复 湖东呀 :
是为了能使用uni.switchTab
2022-03-24 18:12
余予娱与愚

余予娱与愚

第一次切换tab,会出现闪屏的问题,请问怎么解决?
2021-07-23 09:50