本篇文章解决的问题如下:

1:uniapp在pages.json中定义的tabbar,在非tabbar页面的时候不会显示,所以自定义了一个tabbar组件。(注意是自定义组件不是官方的custom-tab-bar组件)

2:有些tabbar需要动态变化,会员登陆前和会员登陆后可能会需要在tabbar上面展示不同的项目,所以要做到动态判断

3:uniapp所有页面底部都插入同一个组件(例如版权信息,或右侧悬浮的内容),每个页面都引入一次太过麻烦,所以在main.js里面挂载一次就可以所有页面使用。

一:自定义tabbar组件:(就不需要在pages.json里面再定义tabbar了)

<!--
    @时间:2020-03-16
    @描述:自定义底部导航栏
    @使用:
        在main.js全部引入:
            import tabBar from "@/pages/common/tabBar.vue"
            Vue.component('tabBar', tabBar)
        在需要显示的页面底部添加:
        <view>
            <view>这里是页面内容代码区域</view>       // 其中uni-p-b-98是公共样式类名,表示padding-bottom: 98upx;  设置的98upx是和底部导航栏的高度保持一致,页面的内容就不会被底部导航遮挡住啦
            <view class="uni-p-b-98"></view>       // 最后引入自定义组件,并传当前栏目对应的pagePath到自定义组件,显示当前栏目的选中样式
            <tabBar :pagePath="'/pages/tabBar/home/home'"></tabBar>
        </view>
 -->
<template>
    <view class="uni-tabbar">
        <view class="uni-tabbar__item" v-for="(item,index) in tabbar" :key="index" @tap="changeTab(item)">
            <view class="icon" :class="[item.fontIcon , item.pagePath == pagePath?'uni-active':'']"></view>
            <!-- 上面使用的是字体图标,解决切换页面的时候图标会闪的效果,毕竟每切换一个页面都会闪一下不太好看,可以切换使用下面的图片方式 -->
            <view v-if="false" class="uni-tabbar__bd">
                <view class="uni-tabbar__icon">
                    <image v-if="item.pagePath == pagePath" class="uni-w-42 uni-h-42" mode="aspectFit" :src="item.selectedIconPath"></image>
                    <image v-else class="uni-w-42 uni-h-42" mode="aspectFit" :src="item.iconPath"></image>
                </view>
            </view>
            <view class="uni-tabbar__label" :class="{'active': item.pagePath == pagePath}">
                {{item.text}}
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        props: {
            pagePath: null
        },
        data() {
            return {
                page: 'contact',
                showPage: false,
                containerHeight: 400,
                tabbar: [
                    {
                        "pagePath": "/pages/tabBar/home/home",
                        "iconPath": "/static/tabBar/home.png",
                        "selectedIconPath": "/static/tabBar/home_col.png",
                        "text": "首页",
                        "fontIcon": "icon-shouye"
                    },            // 这里是要动态切换的栏目,先隐藏,动态追加
                    // {
                    //     "pagePath": "/pages/tabBar/manage/manage",
                    //     "iconPath": "/static/tabBar/home.png",
                    //     "selectedIconPath": "/static/tabBar/home_col.png",
                    //     "text": "管理",
                    //     "fontIcon": "icon-guanli"
                    // },
                    {
                        "pagePath": "/pages/tabBar/person/person",
                        "iconPath": "/static/tabBar/person.png",
                        "selectedIconPath": "/static/tabBar/person_col.png",
                        "text": "我的",
                        "fontIcon": "icon-wode"
                    }
                ]
            };
        },
        mounted() {
            // true为判断条件,根据实际的需求替换即可
            if(true) {
                this.tabbar.splice(1,0,
                    {
                        "pagePath": "/pages/tabBar/manage/manage",
                        "iconPath": "/static/tabBar/home.png",
                        "selectedIconPath": "/static/tabBar/home_col.png",
                        "text": "管理",
                        "fontIcon": "icon-guanli"
                    }
                )
            }
        },
        methods: {
            changeTab(item) {
                this.page = item.pagePath;          // 这里使用reLaunch关闭所有的页面,打开新的栏目页面
                uni.reLaunch({
                    url: this.page
                });
            },
        }
    }
</script>
<style lang="scss" scoped>
    [nvue] uni-scroll-view, [nvue] uni-swiper-item, [nvue] uni-view {
        flex-direction: unset;
    }
    [nvue-dir-column] uni-swiper-item, [nvue-dir-column] uni-view {
        flex-direction: unset;
    }
    .uni-tabbar {
        position: fixed;
        bottom: 0;
        z-index: 999;
        width: 100%;
        display: flex;
        justify-content: space-around;
        height: 98upx;
        padding: 16upx 0;
        box-sizing: border-box;
        border-top: solid 1upx #ccc;
        background-color: #fff;
        box-shadow: 0px 0px 17upx 1upx rgba(206, 206, 206, 0.32);
        .uni-tabbar__item {
            display: block;
            line-height: 24upx;
            font-size: 20upx;
            text-align: center;
        }
        .uni-tabbar__icon {
            height: 42upx;
            line-height: 42upx;
            text-align: center;
        }
        .icon {
            display: inline-block;
        }
        .uni-tabbar__label {
            line-height: 24upx;
            font-size: 24upx;
            color: #999;
            &.active {
                color: #1ca6ec;
            }
        }
    }
</style>

然后在各页面中使用组件即可

**注意修改代码中的页面路径**

**注意使用字体图标的话需要先在APP.Vue中引入iconfont.css**

<tabBar :pagePath="'/pages/list/list'"></tabBar>

 **传入的路径用于当前项目高亮**

二:全局挂载自定义组件(在main.js中)

import Vue from 'vue'
Vue.prototype.baseUrl = tools.baseUrl
Vue.config.productionTip = false
import tabBar from "@/components/tabbar/tabbar.vue"
Vue.component('tabBar', tabBar)
import Aside from "@/components/aside/aside.vue"
Vue.component('Aside', Aside)

**注意要放在import Vue之后才行**

然后在各个页面中无须再import,也无须再components注册,直接<Aside></Aside>就可以用了。

发表回复