automated_uniapp/uni_modules/cool-ui/components/cl-page/cl-page.vue

247 lines
4.7 KiB
Vue
Raw Normal View History

2025-01-09 16:16:11 +08:00
<template>
<view
class="cl-page"
:class="[
`theme-${app.theme.name}`,
{
'is-fullscreen': fullscreen,
2025-01-09 16:40:44 +08:00
'is-safe-area-bottom': fullscreen,
2025-01-09 16:16:11 +08:00
},
]"
:style="{
padding: parseRpx(padding),
2025-01-09 16:40:44 +08:00
height
2025-01-09 16:16:11 +08:00
}"
>
<!-- 加载框 -->
<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="{
2025-01-09 16:40:44 +08:00
backgroundColor: background,
backgroundImage: 'url(' + backgroundImage + ')',
2025-01-09 16:16:11 +08:00
}"
></view>
</template>
<script lang="ts">
2025-01-09 16:40:44 +08:00
import { onPageScroll } from "@dcloudio/uni-app";
import { computed, defineComponent, ref, reactive, getCurrentInstance, onMounted } from "vue";
import { useApp, useCool} from "/@/cool";
2025-01-09 16:16:11 +08:00
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,
2025-01-09 16:40:44 +08:00
// 背景图片
backgroundImage: {
type: String,
default: "",
},
2025-01-09 16:16:11 +08:00
},
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();
// 是否显示导航栏
2025-01-09 16:40:44 +08:00
const statusBar = computed(() => {
return info?.isCustomNavbar ? props.statusBar : false;
});
2025-01-09 16:16:11 +08:00
// 背景色
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
2025-01-09 16:40:44 +08:00
h = screenHeight - (statusBar ? statusBarHeight : 0);
2025-01-09 16:16:11 +08:00
if (!info?.isCustomNavbar) {
h -= 44;
2025-01-09 16:40:44 +08:00
h -= statusBarHeight;
2025-01-09 16:16:11 +08:00
}
2025-01-09 16:40:44 +08:00
2025-01-09 16:16:11 +08:00
// #endif
2025-01-09 16:40:44 +08:00
if (props.fullscreen) return h + "px";
2025-01-09 16:16:11 +08:00
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")
2025-01-09 16:40:44 +08:00
.boundingClientRect((a: any) => {
2025-01-09 16:16:11 +08:00
uni.createSelectorQuery()
.in(proxy)
.select(".safe-area-bottom")
2025-01-09 16:40:44 +08:00
.boundingClientRect((b: any) => {
2025-01-09 16:16:11 +08:00
const scrollTop = top + (a?.height || 0) - (b?.bottom || 0);
uni.pageScrollTo({
scrollTop,
duration: 100,
});
})
.exec();
})
.exec();
};
2025-01-09 16:40:44 +08:00
const scrollTop = ref(0);
2025-01-09 16:16:11 +08:00
2025-01-09 16:40:44 +08:00
onPageScroll((e: any) => {
scrollTop.value = e.scrollTop;
});
2025-01-09 16:16:11 +08:00
return {
app,
background,
height,
refs,
setRefs,
2025-01-09 16:40:44 +08:00
scrollTop,
2025-01-09 16:16:11 +08:00
loader,
parseRpx,
statusBar,
};
},
});
</script>