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>
|