211 lines
4.0 KiB
Vue
211 lines
4.0 KiB
Vue
<template>
|
||
<view class="page-container" :style="containerStyle">
|
||
<nav-header
|
||
:title="navTitle"
|
||
:showBack="showBack"
|
||
:backUrl="backUrl"
|
||
:color="navColor"
|
||
:backgroundColor="navBackgroundColor"
|
||
:fixed="fixed"
|
||
:statusBar="statusBar"
|
||
:shadow="shadow"
|
||
:dark="dark"
|
||
:height="navHeight"
|
||
:leftText="leftText"
|
||
:rightText="rightText"
|
||
:leftIcon="showBack ? 'back' : ''"
|
||
@clickLeft="onClickLeft"
|
||
@clickRight="onClickRight"
|
||
@clickTitle="onClickTitle">
|
||
<template #right>
|
||
<slot name="nav-right"></slot>
|
||
</template>
|
||
</nav-header>
|
||
<view class="page-container__content" :style="contentStyle">
|
||
<view class="page-container__divider" v-if="divider"></view>
|
||
<slot></slot>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import NavHeader from '@/components/nav-header/nav-header.vue'
|
||
|
||
export default {
|
||
name: 'PageContainer',
|
||
components: {
|
||
NavHeader
|
||
},
|
||
emits: ['clickLeft', 'clickRight', 'clickTitle'],
|
||
props: {
|
||
// 标题文字
|
||
title: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 是否暗黑模式
|
||
dark: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 是否显示返回按钮
|
||
showBack: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 左侧文字
|
||
leftText: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 右侧文字
|
||
rightText: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 返回页面路径,不传则返回上一页
|
||
backUrl: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 导航栏文字颜色
|
||
navColor: {
|
||
type: String,
|
||
default: '#000000'
|
||
},
|
||
// 导航栏背景颜色
|
||
navBackgroundColor: {
|
||
type: String,
|
||
default: 'transparent'
|
||
},
|
||
// 页面背景颜色(支持渐变)
|
||
backgroundColor: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 是否使用渐变背景
|
||
useGradient: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// 是否固定导航栏在顶部
|
||
fixed: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// 是否包含状态栏
|
||
statusBar: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// 是否显示阴影
|
||
shadow: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 是否显示分隔线
|
||
divider: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 导航栏高度
|
||
navHeight: {
|
||
type: [Number, String],
|
||
default: 44
|
||
},
|
||
// 底部内边距
|
||
paddingBottom: {
|
||
type: String,
|
||
default: '0px'
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
statusBarHeight: 20, // 默认状态栏高度
|
||
navbarHeight: 44, // 导航栏高度
|
||
navTitle: '' // 导航栏标题,避免直接使用prop
|
||
}
|
||
},
|
||
computed: {
|
||
// 容器样式
|
||
containerStyle() {
|
||
if (this.backgroundColor) {
|
||
return 'background: ' + this.backgroundColor;
|
||
}
|
||
if (this.useGradient) {
|
||
return 'background: linear-gradient(180deg, #5FCDFF 0%, #F5F5F5 100%)';
|
||
}
|
||
return 'background-color: #F5F5F5';
|
||
},
|
||
// 内容区样式
|
||
contentStyle() {
|
||
return 'padding-bottom: ' + this.paddingBottom;
|
||
}
|
||
},
|
||
created() {
|
||
this.getStatusBarHeight();
|
||
// 转换导航栏高度
|
||
this.navbarHeight = typeof this.navHeight === 'number' ? this.navHeight : parseInt(this.navHeight);
|
||
// 初始化导航栏标题
|
||
this.navTitle = this.title;
|
||
},
|
||
watch: {
|
||
// 监听title属性变化
|
||
title(newVal) {
|
||
this.navTitle = newVal;
|
||
}
|
||
},
|
||
methods: {
|
||
// 获取状态栏高度
|
||
getStatusBarHeight() {
|
||
uni.getSystemInfo({
|
||
success: (res) => {
|
||
this.statusBarHeight = res.statusBarHeight || 20;
|
||
}
|
||
});
|
||
},
|
||
// 点击左侧
|
||
onClickLeft() {
|
||
this.$emit('clickLeft');
|
||
},
|
||
// 点击右侧
|
||
onClickRight() {
|
||
this.$emit('clickRight');
|
||
},
|
||
// 点击标题
|
||
onClickTitle() {
|
||
this.$emit('clickTitle');
|
||
},
|
||
// 设置标题的公共方法(供父组件调用)
|
||
setNavTitle(title) {
|
||
this.navTitle = title;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.page-container {
|
||
width: 100vw;
|
||
min-height: 100vh;
|
||
box-sizing: border-box;
|
||
|
||
&__content {
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
}
|
||
|
||
&__divider {
|
||
width: 100%;
|
||
height: 4rpx;
|
||
background-color: rgba(0, 0, 0, 0.05);
|
||
position: relative;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 1;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
}
|
||
</style> |