# uni-app 安全区域适配:防止刘海屏遮挡
## 🎯 核心 API
```javascript
// 获取设备安全区域信息
const { safeAreaInsets } = uni.getSystemInfoSync()
console.log(safeAreaInsets)
// 输出:
// {
// top: 44, // 顶部安全距离(刘海屏为44px,普通设备为20px)
// bottom: 34, // 底部安全距离(Home指示器高度)
// left: 0, // 左侧安全距离
// right: 0 // 右侧安全距离
// }
📱 应用场景
1. 自定义导航栏适配
<script setup lang="ts">
// 获取安全区域
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<template>
<!-- 顶部导航栏 -->
<view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="title">页面标题</view>
</view>
</template>
2. 底部工具栏适配
<template>
<!-- 底部工具栏 -->
<view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
<button>操作按钮</button>
</view>
</template>
3. 页面内容区域适配
<template>
<!-- 页面内容区域 -->
<view class="content" :style="{
paddingTop: safeAreaInsets?.top + 'px',
paddingBottom: safeAreaInsets?.bottom + 'px'
}">
<!-- 页面内容 -->
</view>
</template>
⚙️ pages.json 配置
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom" // 使用自定义导航栏才需要手动适配
}
}
]
}
🎨 CSS 方式(备选)
.navbar {
/* CSS 安全区域常量 */
padding-top: constant(safe-area-inset-top); /* iOS 11.0-11.2 */
padding-top: env(safe-area-inset-top); /* iOS 11.2+ */
}
.toolbar {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
🔧 实用代码片段
兜底处理
const { safeAreaInsets } = uni.getSystemInfoSync()
const safeTop = safeAreaInsets?.top || 20 // 默认状态栏高度
const safeBottom = safeAreaInsets?.bottom || 0
组合式函数
// composables/useSafeArea.ts
export const useSafeArea = () => {
const { safeAreaInsets } = uni.getSystemInfoSync()
return {
safeTop: safeAreaInsets?.top || 0,
safeBottom: safeAreaInsets?.bottom || 0,
safeStyle: {
paddingTop: `${safeAreaInsets?.top || 0}px`,
paddingBottom: `${safeAreaInsets?.bottom || 0}px`
}
}
}
H5 端配置
<!-- index.html -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
📋 重点提醒
- ✅ 只有
navigationStyle: "custom"
的页面需要手动适配
- ✅ iPhone X 系列:
top: 44px
, bottom: 34px
- ✅ 普通设备:
top: 20px
, bottom: 0px
- ✅ 使用动态样式绑定:
:style="{ paddingTop: safeAreaInsets?.top + 'px' }"