136 lines
2.8 KiB
Vue
136 lines
2.8 KiB
Vue
<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>
|