1.需求解读
我希望写出如下的tabbar,但又想偷懒不自己写组件(虽然不是很复杂,懒筋犯了),于是采用了u-view的tabbar组件:
2.问题发现
尽管我开启了适配底部安全区选项:
<view>
<up-tabbar
class="tabbar"
:value="value6"
:fixed="true"
:placeholder="true"
@change="(name:any) => (value6 = name)"
:safeAreaInsetBottom="true"
>
<up-tabbar-item text="首页" icon="home"></up-tabbar-item>
<up-tabbar-item text="放映厅" icon="photo"></up-tabbar-item>
<up-tabbar-item text="直播" icon="play-right"></up-tabbar-item>
<up-tabbar-item text="我的" icon="account"></up-tabbar-item>
</up-tabbar>
</view>
</view>
但仍在存在底部安全区无法适配的问题 ,打开调试器可以看到:
打开该选项组件并没有调用uni的api获取到底部安全区高度后赋值给这个块来撑起来底部安全区
3.思考解决
1.我首先采用再添加一个u-safe-bottom
很可惜,结果是仍然不会给这个组件添加高度
2.自己获取高度,给到该安全区一个高度:
1.采用自带的env(safe-area-inset-bottom)
:deep(.u-safe-bottom) {
height: env(safe-area-inset-bottom);
}
以下是一些关键点:
-
环境变量:
env()
函数用于引用环境变量,这些变量通常由浏览器提供,用于处理特定设备的安全区域。例如,env(safe-area-inset-bottom)
返回设备底部安全区域的大小。 -
用途:这个变量在现代浏览器和移动设备上使用,帮助确保网页内容不会被设备的安全区域遮挡。例如,如果设备有一个刘海或圆角,
safe-area-inset-bottom
可以确保底部的内容不会被遮挡。 -
支持情况:
env()
函数及其相关环境变量主要在支持 CSS 环境变量的设备和浏览器中有效。大多数现代 iOS 浏览器和 Android 设备的浏览器都支持它。然而,某些旧设备或不支持环境变量的浏览器可能无法正确渲染这些样式. -
:deep
是 Vue 3 中的一个特殊 CSS 选择器,用于穿透 scoped 样式的作用域限制,允许你将样式应用到组件的子组件中。它在 Vue 的 Scoped CSS 中非常有用,因为 Scoped CSS 默认只应用于当前组件,不会影响子组件或父组件的样式。 -
scoped的样式类名会有一个特殊的后缀避免样式重复,同react的module导入css一个作用,都是避免样式的污染
但是这样的效果并不好:
感觉太长了获取到的安全区高度
2.自己获取
const systemInfo = uni.getSystemInfoSync()
const bottomSafeAreaHeight = systemInfo.screenHeight - systemInfo.safeArea?.bottom
但不同h5,这样的样式不能在小程序的css中引用,并且如果采用内联的方法来设置高度,不:deep这个样式并不会生效。
所以只能采用:deep一步一步修改样式的方法:
<view class="tabBar">
<up-tabbar
:value="value6"
:fixed="true"
:placeholder="false"
@change="(name:any) => (value6 = name)"
:safeAreaInsetBottom="true"
>
<up-tabbar-item text="首页" icon="home"></up-tabbar-item>
<up-tabbar-item text="放映厅" icon="photo"></up-tabbar-item>
<up-tabbar-item text="直播" icon="play-right"></up-tabbar-item>
<up-tabbar-item text="我的" icon="account"></up-tabbar-item>
</up-tabbar>
<view :style="{ paddingBottom: bottomSafeAreaHeight + 'rpx' }"></view>
</view>
:deep(.u-tabbar--fixed) {
position: static !important;
}
.tabBar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: white;
z-index: 1;
}
首先取消原来的fixed,给一个新底部块用于安全区,取消原有的占位块,fixed这个封装的tabbar,注意:
这里仍需要一个占位块,或页最后一个元素给一个margin-bottom来保证上面的元素不被遮挡
我选择后者:
注意::v-deep
会应用在它穿透的子组件的样式上,因此穿透后的样式会继承父组件样式的特异性规则。如果在穿透选择器中使用了 ID 选择器、类选择器等,它们的优先级会按原规则计算。
效果如下:
至此解决了原有组件的底部安全区失效的问题