记录自定义uniapp顶部实现导航效果

388 阅读1分钟

废话少说!!!

打开HBuliderX、新建项目后、在pages文件夹下新建NavigatBar.vue文件,在computed里获取到系统状态栏高度等数据(很重要),具体如下:

computed:{
    //获取系统状态栏高度
    statusBarHeight(){
            var that = this;
            return uni.getSystemInfoSync().statusBarHeight
    },
    navbarHeight(){
            var that = this;
            return uni.getSystemInfoSync().statusBarHeight + that.conf.height + 'px'
    },
    screenWidth(){
            return uni.getSystemInfoSync().screenWidth;
    }
}

同时构建整体结构如下:

<template>
<view class="nav-bar" :style="{width:screenWidth + 'px'}">
    <view class="content" :style="{'margin-top':statusBarHeight + 'px'}">
        <view class="left">
                <image style="width: 56rpx; height: 56rpx;" src="../../static/c.png"></image>
        </view>
        <image style="width: 220rpx;height: 36rpx;" src="../../static/Bestial King.png"></image>
        <view class="right">
            <span v-if="language == 'Ch'" @click="changeLanguage('En')">En</span>
            <span v-else @click="changeLanguage('Ch')">中文</span>
            <image @click="checked = !checked" v-if="checked" style="width: 48rpx;height: 48rpx;" src="../../static/x.png"></image>
            <image @click="checked = !checked" v-else src="../../static/menu.png" style="width: 48rpx;height: 48rpx;"></image>
        </view>
    </view>
    <view class="site" :style="{'margin-top':statusBarHeight}">

    </view>
    <view class="select" v-if="checked" :style="{'top':statusBarHeight + 44 + 'px'}">
            <span v-for="item in selectData"
             :key="item.index"
             @click='navGatTo(item.index)'
             :class="{'active':item.index == value}">
                    {{item.value}}
            </span>
    </view>
</view>
</template>

将nav-bar的宽度设置为页面宽度,而高度由内部的content设置的系统状态栏撑起来、其中nav-bar下由三部分构成:content为状态栏、site目的是为了占位、select为下拉菜单作为导航使用。 完整代码如下:

<template>
    <view class="nav-bar" :style="{width:screenWidth + 'px'}">
        <view class="content" :style="{'margin-top':statusBarHeight + 'px'}">
            <view class="left">
                <image style="width: 56rpx; height: 56rpx;" src="../../static/c.png"></image>
            </view>
            <image style="width: 220rpx;height: 36rpx;" src="../../static/Bestial King.png"></image>
            <view class="right">
                <span>En</span>
                <image @click="checked = !checked" v-if="checked" style="width: 48rpx;height: 48rpx;" src="../../static/x.png"></image>
                <image @click="checked = !checked" v-else src="../../static/menu.png" style="width: 48rpx;height: 48rpx;"></image>
            </view>
        </view>
        <view class="site" :style="{'margin-top':statusBarHeight}">

        </view>
        <view class="select" v-if="checked" :style="{'top':statusBarHeight + 44 + 'px'}">
            <span v-for="item in selectData"
             :key="item.index"
             @click='navGatTo(item.index)'
             :class="{'active':item.index == value}">
                    {{item.value}}
            </span>
        </view>
    </view>
</template>

<script>
	export default {
            data() {
                return {
                    checked:false,
                    language:'Ch',
                    selectData:[
                        {value:'首页',index:1},
                        {value:'NFT',index:2},
                        {value:'个人中心',index:3},
                        {value:'邀请',index:4},
                    ]
                }
            },
            props:['value'],
		
            methods: {
                // 页面跳转
                navGatTo(i){
                    switch (i){
                        case 1:
                            uni.redirectTo({
                                url:'/pages/index'
                            })
                            break;
                        case 2:
                            uni.redirectTo({
                                url:'/pages/NFT'
                            })
                            break;
                        case 3:
                            uni.redirectTo({
                                url:'/pages/PerSonal'
                            })
                            break;
                        case 4:
                            uni.redirectTo({
                                url:'/pages/Invite'
                            })
                            break;
                        default:
                            break;
                    }
                }
            },
            computed:{
                //获取系统状态栏高度
                statusBarHeight(){
                    var that = this;
                    return uni.getSystemInfoSync().statusBarHeight
                },
                navbarHeight(){
                    var that = this;
                    return uni.getSystemInfoSync().statusBarHeight + that.conf.height + 'px'
                },
                screenWidth(){
                    return uni.getSystemInfoSync().screenWidth;
                }
            }
	}
</script>

<style lang="scss" scoped>
@import '../../styles/mixin.scss';
.nav-bar{
	position: relative;
	.content {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		z-index: 1000;
		background-color: #1F2130;
		padding:16rpx 24rpx;
		@include layout-flex-r-sb;
		@include layout-flex-r-ac;
		.right{
			@include layout-flex-r-ac;
			span{
				font-size: 28rpx;
				color: #fff;
				margin-right: 24rpx;
			}
		}
	}
	.select{
		position:fixed;
		width: 100%;
		z-index:1000;
		background-color: #1F2130;
		@include layout-flex-c-sa;
		text-align: center;
		span{
			font-size: 28rpx;
			color: #787D9D;
			line-height: 33px;
		}
		.active{
			color: #fff;
			text-decoration: underline;
		}
	}
}
</style>

其中style里引入的mixin.scss为自定义的混入样式,本文中用到的类似@include layout-flex-r-sb;的为flex定位