automated_uniapp/uni_modules/cool-fixtures/components/fix-base-style/fix-base-style.vue

136 lines
2.8 KiB
Vue
Raw Permalink Normal View History

2025-01-09 16:40:44 +08:00
<template>
<view
:style="{
paddingTop: seatHeight + 'px',
}"
class="layer"
>
<view
:style="{
...basePosition,
width: '100%',
}"
>
<view :style="{ position: 'absolute', ...baseBackground }"></view>
<view class="fix-base-style" :style="baseStyle" :class="[`fix-base-style-${index}`]">
<slot></slot>
</view>
</view>
</view>
</template>
<script lang="ts" setup name="fix-base-style">
import { computed, watch, ref, nextTick, getCurrentInstance } from "vue";
import { baseProps } from "../../hooks";
const { proxy }: any = getCurrentInstance();
const { statusBarHeight = 0 } = uni.getSystemInfoSync();
// 定义属性,简化默认对象的写法
const props = defineProps({
...baseProps,
// 背景跟随子元素的间距圆角
flowInner: {
type: Boolean,
default: true,
},
statusBar: {
type: Boolean,
default: false,
},
index: {
type: Number,
default: 0,
},
});
// 计算 baseStyle使用解构优化
const baseStyle = computed(() => {
const { marginTop, marginBottom, marginLR, padding, borderTopLR, borderBottomLR } =
props.styleSpacing;
const { color } = props.styleColor;
return {
margin: `${marginTop}rpx ${marginLR}rpx ${marginBottom}rpx ${marginLR}rpx`,
color: color,
padding: `${padding}rpx`,
borderRadius: `${borderTopLR}rpx ${borderTopLR}rpx ${borderBottomLR}rpx ${borderBottomLR}rpx`,
};
});
const baseBackground = computed(() => {
const { backgroundColor, opacity } = props.styleColor;
const { marginTop, marginBottom, marginLR, borderTopLR, borderBottomLR } = props.styleSpacing;
let flow: any = {
left: 0,
top: 0,
right: 0,
bottom: 0,
};
if (props.flowInner) {
flow = {
left: `${marginLR}rpx`,
top: `${marginTop}rpx`,
right: `${marginLR}rpx`,
bottom: `${marginBottom}rpx`,
borderRadius: `${borderTopLR}rpx ${borderTopLR}rpx ${borderBottomLR}rpx ${borderBottomLR}rpx`,
};
}
return {
backgroundColor: backgroundColor,
opacity: opacity,
zIndex: -1,
...flow,
};
});
const basePosition = computed(() => {
const { top, mode, zIndex } = props.position;
let topPos = top;
if (props.statusBar) topPos = topPos + statusBarHeight;
return {
top: `${topPos}px`,
position: mode,
zIndex: zIndex,
};
});
const seatHeight = ref(0);
watch(
() => props.position,
async (position) => {
if (position.isSeat && position.mode === "fixed") {
refreshSeat();
}
},
{
deep: true,
immediate: true,
},
);
function refreshSeat() {
nextTick(() => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(proxy)
// #endif
.select(`.fix-base-style-${props.index}`)
.boundingClientRect((res: any) => {
seatHeight.value = res.height;
})
.exec();
});
}
</script>
<style lang="scss" scoped>
.layer {
width: 100%;
position: relative;
.fix-base-style {
height: auto;
box-sizing: border-box;
}
}
</style>