uniapp自定义导航栏

138 阅读1分钟

微信小程序

<template>
    <view class="nav-box flex-align" :style="{'height':height+'px','background':bgColor}">
        <!-- 胶囊位置信息 -->
        <view class="nav-main flex-align" :style="{height: navBarHeight+'px'}">
            <view class="nav-main-back" @click="back" v-if="backIcon">
                <uni-icons type="back" size="26" color="#fff"></uni-icons>
            </view>
            <text class="nav-main-title">{{title}}</text>
        </view>
    </view>
</template>

<script>
    export default {
        props: {
            bgColor: {
                type: String,
                default: ""
            },
            backIcon: {
                type: Boolean,
                default: true
            },
            title: {
                type: String,
                default: ""
            }
        },
        data() {
            return {
                //总高度
                height: 0,
                //胶囊位置信息
                menuButtonRect: {},
                //状态栏的高度
                statusBarHeight: 0,
                //导航栏的高度
                navBarHeight: 0
            }
        },
        created() {
            this.getHeight();
            this.getPages()
        },
        methods: {
            //获取屏幕导航栏高度
            getHeight() {
                if (wx.canIUse('getMenuButtonBoundingClientRect')) {
                    let sysInfo = wx.getSystemInfoSync(); //状态栏的高度
                    this.statusBarHeight = sysInfo.statusBarHeight;
                    // 胶囊位置信息
                    let rect = wx.getMenuButtonBoundingClientRect();
                    this.menuButtonRect = JSON.parse(JSON.stringify(rect));
                    // 导航栏高度
                    let navBarHeight = (rect.top - sysInfo.statusBarHeight) * 2 + rect.height;
                    this.navBarHeight = navBarHeight;
                    // 自定义导航栏的高度
                    this.height = sysInfo.statusBarHeight + navBarHeight;
                } else {
                    wx.showToast({
                        title: '您的微信版本过低,界面可能会显示不正常',
                        icon: 'none',
                        duration: 4000
                    });
                }
            },
            // 判断是否有上一页
            getPages() {
                let pages = getCurrentPages(); // 获取当前页面栈的实例
                let currPage = pages[pages.length - 1]; //当前页面
                let prevPage = pages[pages.length - 2]; //上一个页面
                this.path = prevPage ? prevPage.$page.fullPath : ''
            },
            //返回
            back() {
                if (this.path) {
                    uni.navigateBack({
                        delta: 1
                    })
                } else {
                    uni.switchTab({
                        url: 'home'
                    })
                }
            },
        }
    }
</script>

<style lang="scss" scoped>
    .flex-align {
        display: flex;
        align-items: center;
    }

    .nav-main {
        width: 100%;
        position: relative;
        text-align: center;

        .nav-main-back {
            position: absolute;
            left: 10rpx;
        }

        .nav-main-title {
            width: 100%;
            color: #fff;
        }
    }
</style>


// 使用
<custom-nav title="我的" ></custom-nav>

效果图:

image.png

来源链接:blog.csdn.net/Start2019/a…

来源链接:blog.csdn.net/Joye_7y/art…

H5和app

<template>
    <view class="nav-box flex-align" :style="{'background':bgColor,'padding-top': statusBarHeight+'rpx'}">
        <!-- 我是插槽 -->
        <view v-if="isSlot">
            <slot name="content"></slot>
        </view>
        <!-- 胶囊位置信息 -->
        <view class="nav-main flex-align" :style="{'height':height+'rpx'}" v-else>
            <view class="nav-main-back">
                <image class="back" :src="images[isLeft ? 'back' :'home']" mode="heightFix"
                    @click="back" v-if="backIcon"></image>
            </view>
            <text class="nav-main-title">{{title}}</text>
            <!-- 右上角插槽 -->
            <slot name="right"></slot>
        </view>
    </view>
</template>

<script>
    const IMAGES = {
        back: '返回键',
        home: '首页'
    }
    export default {
        props: {
            bgColor: {
                type: String,
                default: ""
            },
            isSlot: {
                type: Boolean,
                default: false
            },
            backIcon: {
                type: Boolean,
                default: true
            },
            title: {
                type: String,
                default: ""
            },
            source: {
                type: String,
                default: ""
            },
            fixedPath: {
                type: String,
                default: ""
            }
        },
        watch: {
            title() {},
            source() {}
        },
        computed: {
            isLeft() {
                let hasBack = false
                // #ifdef H5
                if (history.length > 1) {
                    hasBack = true
                }
                // #endif
                return this.path || this.source || hasBack
            }
        },
        data() {
            return {
                images: IMAGES,
                //总高度
                // #ifdef APP-PLUS
                height: 80,
                // #endif
                // #ifdef H5
                height: 100,
                // #endif
                //胶囊位置信息
                menuButtonRect: {},
                //状态栏的高度
                statusBarHeight: 0,
                path: ''
            }
        },
        created() {
            // #ifdef APP-PLUS
            this.getHeight();
            // #endif
            this.getPages()
        },
        methods: {
            //获取屏幕导航栏高度
            getHeight() {
                 this.statusBarHeight = this.getStatusBarHeight().statusBarHeight
            },
            // 判断是否有上一页
            getPages() {
                let pages = getCurrentPages(); // 获取当前页面栈的实例
                let currPage = pages[pages.length - 1]; //当前页面
                let prevPage = pages[pages.length - 2]; //上一个页面
                this.path = prevPage ? prevPage.$page.fullPath : ''
            },
            //返回
            back() {
                // 固定返回某个页面
                if (this.fixedPath) {
                    this.$util.redirectTo(this.fixedPath, {}, 'redirectTo')
                    return
                }
                // 返回来源页
                if (this.source) {
                    this.$util.redirectTo(this.source, {}, 'redirectTo')
                } else if (this.path) {
                    // 返回上一页
                    uni.navigateBack({
                        delta: 1
                    })
                } else {
                    // #ifdef H5
                    if (history.length > 1) {
                        history.back()
                    } else {
                        uni.switchTab({
                            url: '首页'
                        })
                    }
                    // #endif
                    // #ifdef APP-PLUS
                    uni.switchTab({
                        url: '首页'
                    })
                    // #endif
                }
            },
            getStatusBarHeight() {
                const systemInfo = uni.getSystemInfoSync()
                let statusBarHeight = systemInfo.statusBarHeight * 2
                // 总高度=状态栏的高度+导航栏高度
                let totalHeight = statusBarHeight + 80
                // #ifdef H5
                totalHeight = 100
                // #endif
                return {
                    statusBarHeight,
                    totalHeight
                }
            }
        }
    }
</script>

<style lang="scss" scoped>
    .nav-box {
        width: 100%;

        .nav-main {
            width: 100%;
            position: relative;
            text-align: center;

            .nav-main-back {
                position: absolute;
                left: 30rpx;

                .back {
                    height: 42rpx;
                }
            }

            .nav-main-title {
                width: 100%;
                font-size: 35rpx;
                color:#3D3D3D;
            }
        }
    }
</style>
<custom-nav :isSlot="true">
    <block slot="content">
        <view class="index-navbar flex-align pl-3">
            <view class="font-bold ">
                我是插槽
            </view>
        </view>
    </block>
</custom-nav>

效果图如下:

image.png

<custom-nav></custom-nav>

效果图如下:

image.png

<custom-nav title="无返回键" :backIcon="false"></custom-nav>

效果图如下:

image.png

<custom-nav title="消息" :back-icon="false">
    <view class="read " slot="right" @click="allRead">
        全部已读
    </view>
</custom-nav>

效果图如下:

image.png