SafeCapsaulContainer 小程序·安全·胶囊·容器组件
介绍
SafeCapsaulContainer
是一个用于自动处理小程序顶部状态栏区域的容器组件。
- 1、它会自动调整 标题栏 内容区域的安全顶部距离,使其与小程序右上角胶囊一致
- 2、它会自动设置 标题栏 的上下对其位置,使其与 小程序右上角胶囊 保持 上下居中
- 3、并提供了固定顶部 、 修改背景颜色 设置左右边距 的功能。
- 4、当使用
fixed
模式时,组件会自动添加一个占位元素,以防止页面内容被遮挡
功能特性
- 自动适配顶部状态栏高度
- 内容区域与胶囊按钮高度对齐
- 支持固定顶部模式
- 可自定义背景色
- 支持左右内边距调整
- 自动处理内容垂直居中
使用示例
代码:
html
<template>
<SafeCapsaulContainer :fixed="true">
<!-- 这里的标题栏内容直接使用 wot组件 -->
<wd-navbar
title="我的报告"
left-arrow
@click-left="handleClickLeft"
custom-class="custom-navbar"
></wd-navbar>
</SafeCapsaulContainer>
<!-- ......其他内容省略....... -->
</template>
效果展示:

Attributes属性
Props 可选的传入数值
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
fixed | 是否固定在顶部 | Boolean | false |
bgColor | 背景颜色 | String | #ffffff(纯白) |
showBgColor | 是否显示背景色 | Boolean | true |
showPlaceholder | 是否显示占位元素(固定顶部时可能需要) | Boolean | true |
paddingLeft | 左侧内边距(默认单位:px,用户只需传入纯数字即可) | Number | 0 |
paddingRight | 右侧内边距默认单位:px,用户只需传入纯数字即可)) | Number | 0 |
默认插槽
名称 | 说明 |
---|---|
default | 默认插槽,用于放置内容 |
注意事项
- 当使用
fixed
模式时,组件会自动添加一个占位元素,以防止页面内容被遮挡 - 内容区域会自动垂直居中对齐
- z-index 默认设置为 998,若有项目有用到遮罩层,可能需要根据实际场景调整
- 组件会自动获取胶囊按钮的位置信息来调整布局
样式定制
组件提供了基础的样式定制能力:
- 通过
bgColor
属性可以修改背景色 - 通过
paddingLeft
和paddingRight
可以调整内容区域的水平间距 - 内容区域默认垂直居中,使用了
position子绝父相
和transform
实现
示例场景
1. 固定顶部导航栏
html
<template>
<safe-capsaul-container
:fixed="true"
:bgColor="#f8f8f8"
:paddingLeft="16"
:paddingRight="16"
>
<view class="nav-content">
<text>导航栏标题</text>
</view>
</safe-capsaul-container>
</template>
2. 普通内容区域
html
<template>
<safe-capsaul-container
:paddingLeft="12"
:paddingRight="12"
>
<view class="content">
<text>普通内容</text>
</view>
</safe-capsaul-container>
</template>
更新日志
1.0.0
- 首次发布
- 支持基础的顶部安全区域适配
- 支持固定顶部模式
- 提供基础的样式定制能力
源代码
html
<!--
description: 自动避开顶部状态栏区域,并且是与胶囊保持一样的高度
-->
<template>
<view class="safe-top-container" :style="fixedLayoutStyle" :class="{ 'fixed-wrapper': fixed }">
<view class="outer-box" :style="{ width: '100%', height: `${capsualHeight}px`, position: 'relative' }">
<view class="inner-box" :style="diyInnerBoxStyle">
<slot></slot>
</view>
</view>
</view>
<!-- 配一个不脱离文档流的假盒子,使得页面主要元素不会被遮住 -->
<view v-if="fixed" :style="{ height: `${capsualTop + capsualHeight}px` }"></view>
</template>
<script setup>
const props = defineProps({
// 固定在顶部
fixed: {
type: Boolean,
default: false,
},
// 背景色
bgColor: {
type: String,
default: '#ffffff',
},
// 是否显示背景色
showBgColor: {
type: Boolean,
default: true,
},
// 显示占位(如果开启固定到顶部可能会用到
showPlaceholder: {
type: Boolean,
default: true,
},
// 左侧内边距
paddingLeft: {
type: Number,
default: 0,
},
// 右侧内边距
paddingRight: {
type: Number,
default: 0,
},
})
// 旧版·顶部安全距离
// const safeTop = ref(0)
// 右上角的胶囊信息
const capsualTop = ref(0)
const capsualWidth = ref(0)
const capsualHeight = ref(0)
const capsualLeft = ref(0)
const capsualRight = ref(0)
// 固定布局样式
const fixedLayoutStyle = computed(() => ({
width: "100%",
paddingTop: `${capsualTop.value}px`, // 来自胶囊的顶部距离
// paddingLeft: `${props.paddingLeft}px`, // 传入的左边距 ----- 不要写这里,不然底部的线条会变短
// paddingRight: `${props.paddingRight}px`, // 传入的右边距
backgroundColor: props.showBgColor ? props.bgColor : "transparent",
}))
const diyInnerBoxStyle = computed(() => ({
// height: `${capsualHeight.value}px`,
width: "100%",
paddingLeft: `${props.paddingLeft}px`, // 传入的左边距
paddingRight: `${props.paddingRight}px`, // 传入的右边距
// 这样子实现上下居中
position: "absolute",
top: "50%",
transform: "translateY(-50%)",
}))
onMounted(async () => {
// const { statusBarHeight } = uni.getSystemInfoSync() // 旧版·获取状态栏的高度
// safeTop.value = statusBarHeight // 旧版·状态栏的高度
const capsaulInfo = uni.getMenuButtonBoundingClientRect() // 获取胶囊的信息 {width,height,top,left,right 单位:px}
capsualTop.value = capsaulInfo.top
capsualWidth.value = capsaulInfo.width
capsualHeight.value = capsaulInfo.height
capsualLeft.value = capsaulInfo.left
capsualRight.value = capsaulInfo.right
console.log("-------------------------《SafeTopContainer》信息:-------------------------")
console.log("胶囊信息", capsaulInfo)
console.log("整体计算样式", fixedLayoutStyle.value)
console.log("插槽计算样式", diyInnerBoxStyle.value)
})
</script>
<style scoped lang="scss">
.fixed-wrapper {
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 998; // 有些wot组件的遮罩层可能是999,数值太大了的话会导致这个还是白色的
}
</style>