automated_uniapp/uni_modules/cool-ui/components/cl-page/cl-page.vue
2025-01-09 16:40:44 +08:00

247 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view
class="cl-page"
:class="[
`theme-${app.theme.name}`,
{
'is-fullscreen': fullscreen,
'is-safe-area-bottom': fullscreen,
},
]"
:style="{
padding: parseRpx(padding),
height
}"
>
<!-- 加载框 -->
<cl-loading-mask
fullscreen
:loading="loader.loading"
:text="loader.text"
:border="loader.border"
/>
<!-- 提示 -->
<cl-toast :ref="setRefs('toast')" />
<!-- 确认框 -->
<cl-confirm :ref="setRefs('confirm')" />
<!-- 状态栏 -->
<!-- #ifndef MP-ALIPAY -->
<cl-status-bar v-if="statusBar" :background-color="statusBarBackground" />
<!-- #endif -->
<!-- 内容插槽 -->
<slot></slot>
<!-- 底部安全区域 -->
<view class="safe-area-bottom" v-if="!fullscreen"></view>
</view>
<!-- 背景色 -->
<view
class="cl-page__bg"
:style="{
backgroundColor: background,
backgroundImage: 'url(' + backgroundImage + ')',
}"
></view>
</template>
<script lang="ts">
import { onPageScroll } from "@dcloudio/uni-app";
import { computed, defineComponent, ref, reactive, getCurrentInstance, onMounted } from "vue";
import { useApp, useCool} from "/@/cool";
import { parseRpx } from "/@/cool/utils";
import { isString } from "lodash-es";
export default defineComponent({
name: "cl-page",
props: {
// 是否全屏显示高度100%
fullscreen: Boolean,
// 內间距
padding: {
type: [Number, String],
default: 0,
},
// 是否显示状态栏
statusBar: {
type: Boolean,
default: true,
},
// 状态栏背景色
statusBarBackground: String,
// 页面背景色
backgroundColor: String,
// 背景图片
backgroundImage: {
type: String,
default: "",
},
},
setup(props) {
const { refs, setRefs, router } = useCool();
const app = useApp();
const info = router.info();
const {
statusBarHeight = 0,
screenHeight,
windowHeight,
safeAreaInsets,
} = uni.getSystemInfoSync();
const { proxy }: any = getCurrentInstance();
// 是否显示导航栏
const statusBar = computed(() => {
return info?.isCustomNavbar ? props.statusBar : false;
});
// 背景色
const background = computed(() => {
return (
props.backgroundColor ||
router.info()?.style?.backgroundColor ||
router.globalStyle.backgroundColor ||
"#ffffff"
);
});
// 全屏高
const height = computed(() => {
if (!props.fullscreen) {
return "auto";
}
let h = 0;
// #ifdef H5
h = windowHeight;
// #endif
// #ifndef H5
h = screenHeight - (statusBar ? statusBarHeight : 0);
if (!info?.isCustomNavbar) {
h -= 44;
h -= statusBarHeight;
}
// #endif
if (props.fullscreen) return h + "px";
return h - (safeAreaInsets?.bottom || 0) + "px";
});
// 加载框配置
const loader = reactive({
loading: false,
border: false,
text: "加载中",
});
// 显示加载框
function showLoading(options?: ClLoading.MaskOptions) {
loader.loading = true;
if (isString(options)) {
loader.text = options;
} else {
Object.assign(loader, options);
}
}
// 隐藏加载框
function hideLoading() {
loader.loading = false;
}
// 提示框
function showToast(options: ClToast.Options) {
refs.toast?.open(options);
}
// 确认框
function showConfirm(options: ClConfirm.Options) {
refs.confirm?.open(options);
}
// 提示框
function showTips(message: string, callback?: () => void) {
refs.confirm?.open({
title: "提示",
message,
showCancelButton: false,
callback,
} as ClConfirm.Options);
}
// 扩展
const page = router.currentPage();
if (page) {
page["cl-page"] = {
loaded: false,
showLoading,
hideLoading,
showToast,
showConfirm,
showTips,
};
onMounted(() => {
page["cl-page"].loaded = true;
});
}
// 滚动事件
proxy.$root.scrollTo = (top: number) => {
// 减去自定义导航栏高度
top -= info?.isCustomNavbar ? statusBarHeight : 0;
// 减去间距
if (props.padding) {
const [t] = parseRpx(props.padding).split(" ");
top -= uni.upx2px(parseInt(t));
}
uni.createSelectorQuery()
.in(proxy)
.select(".cl-page")
.boundingClientRect((a: any) => {
uni.createSelectorQuery()
.in(proxy)
.select(".safe-area-bottom")
.boundingClientRect((b: any) => {
const scrollTop = top + (a?.height || 0) - (b?.bottom || 0);
uni.pageScrollTo({
scrollTop,
duration: 100,
});
})
.exec();
})
.exec();
};
const scrollTop = ref(0);
onPageScroll((e: any) => {
scrollTop.value = e.scrollTop;
});
return {
app,
background,
height,
refs,
setRefs,
scrollTop,
loader,
parseRpx,
statusBar,
};
},
});
</script>