215 lines
5.3 KiB
Vue
215 lines
5.3 KiB
Vue
<script setup>
|
|
/**
|
|
* @desc 通用布局组件
|
|
*/
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
// import LoginPopup from './login-popup.vue';
|
|
import { getSystemSafeArea, getSafeTopHeight, getSystemInfo, isEmpty } from '@/common/common.js';
|
|
import { useUserStore } from '@/store/user';
|
|
import { useSystemInfo } from '@/hooks/useSystemInfo.js';
|
|
const { navHeight } = useSystemInfo();
|
|
const props = defineProps({
|
|
showBgImage: {
|
|
// 是否展示导航栏
|
|
type: Boolean,
|
|
default: () => {
|
|
return false;
|
|
},
|
|
},
|
|
showNav: {
|
|
// 是否展示导航栏
|
|
type: Boolean,
|
|
default: () => {
|
|
return true;
|
|
},
|
|
},
|
|
navTitle: {
|
|
//标题
|
|
type: String,
|
|
default: () => {
|
|
return '';
|
|
},
|
|
},
|
|
// navPlaceholder: {
|
|
// //是否生成一个等高元素,防止塌陷
|
|
// type: Boolean,
|
|
// default: () => {
|
|
// return false;
|
|
// },
|
|
// },
|
|
navShowReturn: {
|
|
//是否显示返回图标
|
|
type: Boolean,
|
|
default: () => {
|
|
return false;
|
|
},
|
|
},
|
|
navShowNavBar: {
|
|
//是否显示更多图标
|
|
type: Boolean,
|
|
default: () => {
|
|
return false;
|
|
},
|
|
},
|
|
navColor: {
|
|
//标题背景颜色
|
|
type: String,
|
|
default: () => {
|
|
return '#fff';
|
|
},
|
|
},
|
|
bgColor: {
|
|
//标题字体、icon颜色
|
|
type: String,
|
|
default: () => {
|
|
return '#fbfbfd';
|
|
},
|
|
},
|
|
titleColor: {
|
|
//标题字体、icon颜色
|
|
type: String,
|
|
default: () => {
|
|
return '#1D1D1F';
|
|
},
|
|
},
|
|
titleText: {
|
|
// 顶部标题文字
|
|
type: String,
|
|
default: () => {
|
|
return '';
|
|
},
|
|
},
|
|
// showLogin: {
|
|
// // 唤起登录
|
|
// type: Boolean,
|
|
// default: () => {
|
|
// return false;
|
|
// },
|
|
// },
|
|
});
|
|
const emit = defineEmits(['getContentHeight', 'loginStatus']);
|
|
const safeAreaInsetTop = ref(false); //是否开启顶部安全区适配
|
|
const viewHeight = ref(0); //可用高度
|
|
const pageHeight = ref(0); //页面高度
|
|
const pageWidth = ref(getSystemInfo().windowWidth);
|
|
const hasTabbar = ref(false);
|
|
const user = useUserStore();
|
|
const navPlaceholder = ref(false);
|
|
// #ifndef MP-WEIXIN
|
|
navPlaceholder.value = false;
|
|
// #endif
|
|
// #ifdef MP-WEIXIN
|
|
navPlaceholder.value = true;
|
|
// #endif
|
|
|
|
/**
|
|
* @desc 返回上一页
|
|
*/
|
|
const returnBack = () => {
|
|
uni.navigateBack(1);
|
|
};
|
|
|
|
/**
|
|
* @desc 返回内容部分的高度
|
|
*/
|
|
const contentHeight = () => {
|
|
emit('getContentHeight', {
|
|
viewHeight: viewHeight.value,
|
|
pageHeight: pageHeight.value,
|
|
});
|
|
};
|
|
|
|
const showSideNav = ref(false);
|
|
// 关闭/打开侧边弹出层
|
|
const operaSideNav = () => {
|
|
showSideNav.value = !showSideNav.value;
|
|
};
|
|
|
|
// 关闭登录弹窗
|
|
// const onCloseLogin = () => {
|
|
// const status = isEmpty(user.userToken); // true 为空,false为已登录
|
|
// emit('loginStatus', status);
|
|
// };
|
|
|
|
onMounted(() => {
|
|
// #ifndef MP-ALIPAY
|
|
safeAreaInsetTop.value = true;
|
|
// #endif
|
|
uni.showTabBar({
|
|
success() {
|
|
hasTabbar.value = true;
|
|
},
|
|
fail() {
|
|
hasTabbar.value = false;
|
|
},
|
|
complete() {
|
|
pageHeight.value = getSystemSafeArea();
|
|
if (props.showNav) {
|
|
viewHeight.value = pageHeight.value - getSafeTopHeight();
|
|
} else {
|
|
viewHeight.value = pageHeight.value;
|
|
}
|
|
contentHeight();
|
|
},
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<view class="absolute left-[50%] right-0 top-0 translate-x-[-50%]" :style="{ height: `${pageHeight}px`, width: `${pageWidth}px` }">
|
|
<up-navbar
|
|
:title="props?.navTitle"
|
|
:safeAreaInsetTop="safeAreaInsetTop"
|
|
:placeholder="navPlaceholder"
|
|
:bgColor="props.navColor"
|
|
:titleStyle="{ color: props.titleColor }"
|
|
:height="navPlaceholder ? '44px' : `${getSafeTopHeight()}px`"
|
|
class="!flex-1"
|
|
v-if="props.showNav"
|
|
>
|
|
<template #left>
|
|
<view class="flex flex-row items-center gap-[10px]">
|
|
<up-icon name="list-dot" :color="props.titleColor" size="26" @click="operaSideNav" v-if="props.navShowNavBar"></up-icon>
|
|
<!-- #ifndef MP-BAIDU -->
|
|
<up-icon name="arrow-left" :color="props.titleColor" size="24" @click="returnBack" v-if="props.navShowReturn"></up-icon>
|
|
<!-- #endif -->
|
|
</view>
|
|
</template>
|
|
</up-navbar>
|
|
<view
|
|
class="relative left-0 right-0 top-0"
|
|
:style="{
|
|
height: `${viewHeight}px`,
|
|
background: props.bgColor,
|
|
top: navPlaceholder ? 0 : `${getSafeTopHeight()}px`,
|
|
}"
|
|
>
|
|
<view v-if="showBgImage" class="w-full relative">
|
|
<view
|
|
class="w-full h-[calc(200px+var(--status-bar-height))] bg-cover bg-center bg-no-repeat"
|
|
style="background-image: url('/static/test/top2.png')"
|
|
></view>
|
|
<text class="w-full text-[#fff] font-bold text-[20px] absolute left-0 right-0 bottom-[40px] text-center px-[40px]">
|
|
{{ props.titleText }}
|
|
</text>
|
|
</view>
|
|
<view
|
|
class="absolute left-0 right-0 w-full overflow-y-auto"
|
|
:style="{
|
|
top: showBgImage ? 'calc(200px + var(--status-bar-height))' : props.showNav ? 0 : `${navHeight}px`,
|
|
height: showBgImage ? `calc(100% - 200px - var(--status-bar-height))` : '100%',
|
|
}"
|
|
>
|
|
<slot name="content" :row="{ viewHeight, pageHeight }"> </slot>
|
|
</view>
|
|
|
|
|
|
<!-- 登录 -->
|
|
<!-- <LoginPopup :show="props.showLogin" @close="onCloseLogin"></LoginPopup> -->
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<style lang="scss"></style>
|