小程序初始提交

This commit is contained in:
jdc
2025-11-13 10:36:23 +08:00
parent f26b4f9a2f
commit 5db3b180eb
447 changed files with 83351 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<template>
<view class="cl-footer-placeholder" :style="{ height: height + 'px' }" v-if="visible"> </view>
<view class="cl-footer-wrapper" :class="[pt.wrapper?.className]">
<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;
wrapper?: 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 overflow-visible;
padding-bottom: env(safe-area-inset-bottom);
&.is-dark {
@apply bg-surface-900;
}
&__content {
@apply px-3 py-3 overflow-visible;
}
&-wrapper {
@apply fixed bottom-0 left-0 w-full overflow-visible;
}
}
</style>

View File

@@ -0,0 +1,16 @@
import { router } from "@/cool";
import { reactive } from "vue";
export class ClFooterOffset {
private data = reactive({});
set(value: number): void {
this.data[router.path()] = value;
}
get(): number {
return (this.data[router.path()] as number | null) ?? 0;
}
}
export const clFooterOffset = new ClFooterOffset();

View File

@@ -0,0 +1,14 @@
import type { PassThroughProps } from "../../types";
export type ClFooterPassThrough = {
className?: string;
content?: PassThroughProps;
wrapper?: PassThroughProps;
};
export type ClFooterProps = {
className?: string;
pt?: ClFooterPassThrough;
minHeight?: number;
vt?: number;
};