在 Uni-app 中自定义顶部导航栏可以通过使用 custom
配置来实现。下面是一个实现自定义顶部导航栏的完整示例代码。
配置 pages.json
首先,需要在 pages.json
中配置页面使用自定义导航栏:
js
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom" // 使用自定义导航栏
}
}
]
}
示例一
创建自定义导航栏组件
xml
<template>
<view class="custom-navbar">
<view class="left" @click="goBack">
<text class="iconfont icon-back"></text>
</view>
<view class="title">{{ title }}</view>
<view class="right">
<!-- 可以添加其他按钮或图标 -->
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '标题'
}
},
methods: {
goBack() {
uni.navigateBack();
}
}
}
</script>
<style>
.custom-navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: env(safe-area-inset-top);
height: calc(env(safe-area-inset-top) + 44px);
background-color: #fff;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.1);
padding: 0 10px;
box-sizing: border-box;
}
.left, .right {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
}
.title {
flex: 1;
text-align: center;
font-size: 18px;
font-weight: bold;
}
.iconfont {
font-size: 20px;
}
</style>
页面中使用自定义导航栏组件
在需要使用自定义导航栏的页面中引用并使用该组件,例如在 pages/index/index.vue
中:
xml
<template>
<view>
<custom-navbar title="首页"></custom-navbar>
<view class="content">
<!-- 你的页面内容 -->
</view>
</view>
</template>
<script>
import CustomNavbar from '@/components/custom-navbar.vue';
export default {
components: {
CustomNavbar
}
}
</script>
<style>
/* 其他样式 */
.content {
padding-top: calc(env(safe-area-inset-top) + 44px);
}
</style>
示例二
上面的例子,有个问题就是会出现部分屏幕顶部高度不适配,导致元素内容拥挤,不好看。这个例子提供了一种自适应方式处理
为了实现兼容所有手机屏幕的自定义顶部导航栏,可以采用更为通用的方法。我们可以结合设备信息和平台特性来设置合适的导航栏高度。以下是一个更通用的实现方法。
获取系统信息
在页面加载时获取系统信息,确定导航栏的高度。
kotlin
onLoad() {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight; // 获取状态栏高度
if (systemInfo.platform === 'android') {
this.navBarHeight = this.statusBarHeight + 48; // Android 导航栏高度
} else {
this.navBarHeight = this.statusBarHeight + 44; // iOS 导航栏高度
}
}
创建自定义导航栏组件
创建一个自定义导航栏组件,例如 custom-navbar.vue
,并根据获取的状态栏高度动态调整导航栏样式。
xml
<template>
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px', height: navBarHeight + 'px' }">
<view class="left" @click="goBack">
<text class="iconfont icon-back"></text>
</view>
<view class="title">{{ title }}</view>
<view class="right">
<!-- 可以添加其他按钮或图标 -->
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '标题'
}
},
data() {
return {
statusBarHeight: 0,
navBarHeight: 0
};
},
methods: {
goBack() {
uni.navigateBack();
}
},
created() {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight; // 获取状态栏高度
if (systemInfo.platform === 'android') {
this.navBarHeight = this.statusBarHeight + 48; // Android 导航栏高度
} else {
this.navBarHeight = this.statusBarHeight + 44; // iOS 导航栏高度
}
}
}
</script>
<style>
.custom-navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.1);
padding: 0 10px;
box-sizing: border-box;
}
.left, .right {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
}
.title {
flex: 1;
text-align: center;
font-size: 18px;
font-weight: bold;
}
.iconfont {
font-size: 20px;
}
</style>
组件使用自定义导航栏组件
在需要使用自定义导航栏的页面中引用并使用该组件,例如在 pages/index/index.vue
中:
xml
<template>
<view>
<custom-navbar title="首页"></custom-navbar>
<view class="content" :style="{ paddingTop: navBarHeight + 'px' }">
<!-- 你的页面内容 -->
</view>
</view>
</template>
<script>
import CustomNavbar from '@/components/custom-navbar.vue';
export default {
components: {
CustomNavbar
},
data() {
return {
navBarHeight: 0
};
},
created() {
const systemInfo = uni.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight; // 获取状态栏高度
if (systemInfo.platform === 'android') {
this.navBarHeight = statusBarHeight + 48; // Android 导航栏高度
} else {
this.navBarHeight = statusBarHeight + 44; // iOS 导航栏高度
}
}
}
</script>
<style>
/* 其他样式 */
.content {
/* 确保内容不被导航栏遮挡 */
}
</style>
通过动态获取设备的状态栏高度并调整导航栏的样式,可以实现一个兼容所有手机屏幕的自定义顶部导航栏。这个方法确保在不同设备上都能正确显示导航栏,提升用户体验
实例三(vue3 写法)
这个其实跟上面的示例2是一样的,只是我这里用的vue3写法
创建自定义导航栏组件
在 components
文件夹下创建一个自定义导航栏组件,例如 CustomNavbar.vue
。
xml
<template>
<!-- 自定义导航栏的外层容器 -->
<view class="custom-navbar" :style="{ paddingTop: `${statusBarHeight}px`, height: `${navBarHeight}px` }">
<!-- 左侧返回按钮 -->
<view class="left" @click="goBack">
<text class="iconfont icon-back"></text>
</view>
<!-- 中间标题 -->
<view class="title">{{ title }}</view>
<!-- 右侧可以添加其他按钮或图标 -->
<view class="right">
<!-- 预留区域 -->
</view>
</view>
</template>
<script>
import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
name: 'CustomNavbar', // 组件名称
props: {
title: {
type: String,
default: '标题' // 默认标题
}
},
setup() {
// 定义状态栏高度和导航栏高度的响应式变量
const statusBarHeight = ref(0);
const navBarHeight = ref(0);
// 返回上一个页面的方法
const goBack = () => {
uni.navigateBack();
};
// 组件挂载时获取系统信息并计算导航栏高度
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight; // 获取状态栏高度
// 根据平台计算导航栏高度
navBarHeight.value = systemInfo.platform === 'android'
? statusBarHeight.value + 48 // Android 导航栏高度
: statusBarHeight.value + 44; // iOS 导航栏高度
});
// 返回响应式变量和方法供模板使用
return {
statusBarHeight,
navBarHeight,
goBack
};
}
});
</script>
<style scoped>
/* 导航栏样式 */
.custom-navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.1);
padding: 0 10px;
box-sizing: border-box;
}
/* 左右两侧按钮区域样式 */
.left, .right {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
}
/* 中间标题样式 */
.title {
flex: 1;
text-align: center;
font-size: 18px;
font-weight: bold;
}
/* 图标字体样式 */
.iconfont {
font-size: 20px;
}
</style>
组件使用自定义导航栏组件
在需要使用自定义导航栏的页面中引用并使用该组件,例如在 pages/index/index.vue
中:
xml
<template>
<!-- 页面主体 -->
<view>
<!-- 引入并使用自定义导航栏组件 -->
<custom-navbar title="首页"></custom-navbar>
<!-- 页面内容区域,确保内容不被导航栏遮挡 -->
<view class="content" :style="{ paddingTop: `${navBarHeight}px` }">
<!-- 你的页面内容 -->
</view>
</view>
</template>
<script>
import { defineComponent, ref, onMounted } from 'vue';
import CustomNavbar from '@/components/CustomNavbar.vue'; // 引入自定义导航栏组件
export default defineComponent({
components: {
CustomNavbar
},
setup() {
// 定义导航栏高度的响应式变量
const navBarHeight = ref(0);
// 页面挂载时获取系统信息并计算导航栏高度
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight; // 获取状态栏高度
// 根据平台计算导航栏高度
navBarHeight.value = systemInfo.platform === 'android'
? statusBarHeight + 48 // Android 导航栏高度
: statusBarHeight + 44; // iOS 导航栏高度
});
// 返回导航栏高度供模板使用
return {
navBarHeight
};
}
});
</script>
<style scoped>
/* 内容区域样式 */
.content {
/* 确保内容不被导航栏遮挡 */
}
</style>
总结
-
配置
pages.json
:配置页面使用自定义导航栏。 -
创建自定义导航栏组件:
- 模板:定义导航栏的布局,包括左侧返回按钮、中间标题、右侧区域。
- 脚本:使用 Composition API 获取系统信息,计算状态栏和导航栏高度。
- 样式:定义导航栏和内部元素的样式。
-
使用自定义导航栏组件 :在页面中引入并使用该组件,动态调整内容区域的
paddingTop
确保不被导航栏遮挡。
这样,导航栏可以兼容不同设备,动态适应不同状态栏高度,确保良好的用户体验。