uniapp + typeScript + Vue3 自定义头部导航栏

1,436 阅读1分钟

image.png

1、间需要导航的页面开启自定义 "navigationStyle": "custom"

"pages": [
        {
            "path": "pages/tabBar/index",
            "style": {
                "navigationBarTitleText": " ",
                "enablePullDownRefresh": false,
                "navigationStyle": "custom"
            }
        },
      ]

2、获取设备信息,让导航栏适配不同设备 deviceInfo.ts

// 获取导航栏信息
export function getdeviceInfo() {
    const globalData: any = {
        statusBarHeight: 0, // 状态导航栏高度
        navHeight: 0, // 总体高度
        navigationBarHeight: 0, // 导航栏高度(标题栏高度)
        windowHeight: 0, // 可使用窗口高度
    };
    // 状态栏高度
    globalData.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
    // 获取微信胶囊的位置信息 width,height,top,right,left,bottom
    const custom = uni.getMenuButtonBoundingClientRect();
    // 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
    globalData.navigationBarHeight = custom.height + (custom.top - globalData.statusBarHeight) * 2;
    // 总体高度 = 状态栏高度 + 导航栏高度
    globalData.navHeight = globalData.navigationBarHeight + globalData.statusBarHeight;
    return { globalData, custom };
}

3、自定义导航子组件 navBar.vue

<template>
    <view class="top-header-bar" :style="{ background: navBarStyle.backgroundColor }">
        <view class="navbar-box" :style="{ height: `${globalData.navHeight}px` }">
            <view class="navbar-content" :style="{ top: `${custom.top}px`, height: `${custom.height}px` }">
                <view class="logo">
                    <text>logo</text>
                    <!-- <image class="logo-img" mode="aspectFill" :src="`${imgUrl}ic_logo.png`"></image> -->
                </view>
                <!-- 搜索输入框 -->
                <search-input></search-input>
            </view>
        </view>
    </view>
</template>

<script lang="ts" setup>
import { defineProps, reactive, ref } from 'vue';
import searchInput from '@/components/searchInput.vue';
import { getdeviceInfo } from '@/utils/deviceInfo';
import { inject } from 'vue';
const emits = defineEmits(['jumpCityCheck']);
const props = defineProps({
    navBarStyle: {
        type: Object,
        default: () => {
            return {};
        },
    },
});
// 获取导航栏信息
const { globalData, custom } = reactive(getdeviceInfo());
// oss地址
const imgUrl = ref(inject('imgUrl'));
const navBarStyle = ref(props.navBarStyle);
</script>
<style lang="scss" scoped>
.top-header-bar {
    position: fixed;
    left: 0rpx;
    right: 0rpx;
    z-index: 100;
    width: 100%;
    .navbar-box {
        .navbar-content {
            position: absolute;
            left: 0rpx;
            right: 0rpx;
            display: flex;
            align-items: center;
            .logo {
                height: 100%;
                // width: 50rpx;
                display: flex;
                align-items: center;
                margin: 0rpx 13rpx;
                font-size: 26rpx;
                .logo-img {
                    width: 100%;
                    height: 100%;
                }
            }
        }
    }
}
</style>

4、自定义 搜索框 searchInput.vue

<template>
    <view class="container">
        <uni-icons type="search" size="20"></uni-icons>
        <view class="line"></view>
        <input class="search-input" type="text" placeholder="请输入您要搜索的内容" :placeholder-class="'placeholder-style'" />
    </view>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue';
</script>
<style lang="scss" scoped>
$fontSize: 12px;
.container {
    display: flex;
    align-items: center;
    padding: 10rpx 23rpx;
    background: #eeeeee;
    border-radius: 30rpx;

    .line {
        border-left: 2rpx solid #c8cbd4;
        height: 35rpx;
        margin: 0rpx 16rpx;
    }
    ::v-deep .placeholder-style {
        font-size: $fontSize !important;
    }
    .search-input {
        color: #2f3542;
        font-size: $fontSize !important;
    }
}
</style>

后续可加返回操作或者使用插槽自定义内容