Files
WAI_Project_UNIX/uni_modules/cool-ui/components/cl-footer/cl-footer.uvue

124 lines
2.2 KiB
Plaintext

<template>
<view class="cl-footer-placeholder" :style="{ height: height + 'px' }" v-if="visible"> </view>
<view class="cl-footer-wrapper">
<view
class="cl-footer"
:class="[
{
'is-dark': isDark
},
pt.className
]"
v-if="visible"
>
<view class="cl-footer__content" :class="[pt.content?.className]">
<slot></slot>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { getSafeAreaHeight, isDark, isHarmony, parsePt } from "@/cool";
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from "vue";
import type { PassThroughProps } from "../../types";
import { clFooterOffset } from "./offset";
defineOptions({
name: "cl-footer"
});
const props = defineProps({
pt: {
type: Object,
default: () => ({})
},
// 最小高度,小于该高度时,不显示
minHeight: {
type: Number,
default: 30
},
// 监听值,触发更新
vt: {
type: Number,
default: 0
}
});
const { proxy } = getCurrentInstance()!;
type PassThrough = {
className?: string;
content?: PassThroughProps;
};
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 内容高度
const height = ref(0);
// 是否显示
const visible = ref(true);
// 获取内容高度
function getHeight() {
nextTick(() => {
setTimeout(
() => {
uni.createSelectorQuery()
.in(proxy)
.select(".cl-footer")
.boundingClientRect((res) => {
// 获取内容高度
const h = Math.floor((res as NodeInfo).height ?? 0);
// 设置高度
height.value = h;
// 如果内容高度大于最小高度,则显示
visible.value = h > props.minHeight + getSafeAreaHeight("bottom");
// 隔离高度
clFooterOffset.set(visible.value ? h : 0);
})
.exec();
},
isHarmony() ? 50 : 0
);
});
}
onMounted(() => {
watch(
computed(() => props.vt),
() => {
visible.value = true;
getHeight();
},
{
immediate: true
}
);
});
</script>
<style lang="scss" scoped>
.cl-footer {
@apply bg-white;
padding-bottom: env(safe-area-inset-bottom);
&.is-dark {
@apply bg-surface-900;
}
&__content {
@apply px-3 py-3;
}
&-wrapper {
@apply fixed bottom-0 left-0 w-full;
}
}
</style>