初始化项目模板

This commit is contained in:
yangyao committed 2026-01-04 17:53:40 +08:00
1 parent 80fd6a1d4b
commit b3a69a1f27
69 files changed
+11088

No files matched your search

+214
View File
@@ -0,0 +1,214 @@
<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>