uni-app 小程序创建自定义导航栏组件,自适应屏幕高度

在 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>

总结

  1. 配置 pages.json:配置页面使用自定义导航栏。

  2. 创建自定义导航栏组件

    • 模板:定义导航栏的布局,包括左侧返回按钮、中间标题、右侧区域。
    • 脚本:使用 Composition API 获取系统信息,计算状态栏和导航栏高度。
    • 样式:定义导航栏和内部元素的样式。
  3. 使用自定义导航栏组件 :在页面中引入并使用该组件,动态调整内容区域的 paddingTop 确保不被导航栏遮挡。

这样,导航栏可以兼容不同设备,动态适应不同状态栏高度,确保良好的用户体验。

相关推荐
活宝小娜5 分钟前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点8 分钟前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow9 分钟前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o10 分钟前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
Random_index12 分钟前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
开心工作室_kaic1 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā1 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年2 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder3 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727573 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架