最近在项目中使用到了 wot-ui 的浮动面板,这个浮动面板可以设置三个可以拉伸的高度。但在官方示例中,这个三个高度是根据屏幕高度来确定的,对于中间的高度,往往应该适应浮动面板的内容高度更符合直觉。
所以,为了准确的获得这个高度,我通过浮动面板内部元素的顶部和底部元素到屏幕顶部的距离之差,得到了更精确的高度。
前言
浮动面板默认初始化后,高度是固定在底部的,所以浮动面板中的元素到屏幕顶部的距离是固定,这也是为什么我们能够通过这种方式获得更合适的显示高度的原因。
浮动面板
浮动面板主要接收两个参数:初始显示高度 height 和包含三个位置锚点数组 anchors(最小高度,中间高度,最大高度)。所以,我们需要处理的是 anchors[1] 的值。
<template>
<wd-floating-panel v-model:height="height" :anchors="anchors" class="panel"></wd-floating-panel>
</template>
<script lang="ts" setup>
onLoad(() => {
windowHeight.value = uni.getSystemInfoSync().windowHeight
anchors.value = [100, Math.round(0.4 * windowHeight.value), Math.round(0.8 * windowHeight.value)]
height.value = anchors.value[1]
})
</script>
获取高度的距离差
获取元素高度的方法主要使用 uni.getSystemInfoSy API 完成,依次获取 windowHeight 值然后进行相减就行了。
const query = uni.createSelectorQuery();
let panelTop: number;
// 获取顶部元素距离顶部的高度
query
.select(".panel__header")
.boundingClientRect((footerData) => {
panelTop = footerData.top;
})
.exec();
// 获取底部元素距离顶部的高度
query
.select(".panel__footer")
.boundingClientRect((submitData) => {
// 计算高度
let distance = submitData.top - panelTop + 100;
// 防止溢出
distance = distance > windowHeight.value ? windowHeight.value : distance;
// 设置锚点
anchors.value = [100, distance, Math.round(0.8 * windowHeight.value)];
height.value = anchors.value[1];
})
.exec();
});
完整代码示例
<template>
<wd-floating-panel v-model:height="height" :anchors="anchors" class="panel">
<view class="panel__header">浮动面板顶部元素</view>
<view class="panel__content">
<wd-cell-group border>
<wd-cell v-for="item in data" :key="item" :title="item" />
</wd-cell-group>
</view>
<view class="panel__footer">浮动面板底部元素</view>
</wd-floating-panel>
</template>
<script lang="ts" setup>
import { ref } from "vue";
const height = ref<number>(0)
const windowHeight = ref<number>(0)
const anchors = ref<number[]>([])
const data = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
onLoad(() => {
windowHeight.value = uni.getSystemInfoSync().windowHeight
})
onMounted(() => {
const query = uni.createSelectorQuery();
let panelTop: number;
// 获取顶部元素距离顶部的高度
query
.select(".panel__header")
.boundingClientRect((footerData) => {
panelTop = footerData.top;
})
.exec();
// 获取底部元素距离顶部的高度
query
.select(".panel__footer")
.boundingClientRect((submitData) => {
// 计算高度
let distance = submitData.top - panelTop + 100;
// 防止溢出
distance = distance > windowHeight.value ? windowHeight.value : distance;
// 设置锚点
anchors.value = [100, distance, Math.round(0.8 * windowHeight.value)];
height.value = anchors.value[1];
})
.exec();
});
</script>
<style lang="scss" scoped>
.panel {
padding: 0 28px;
}
.panel__header,
.panel__footer {
margin-bottom: 40rpx;
font-size: 28rpx;
text-align: center;
}
</style>
示例效果: