<template>
<view class="custom_bar">
<view
v-if="needSeat"
:style="{
height: heightSize ? heightSize : customBar + 'px'
}"
></view>
<view
class="custom is_fixed"
:style="{
height: heightSize ? heightSize : customBar + 'px',
paddingTop: statusBar + 'px',
backgroundColor: bgColor,
backgroundImage: bgImage,
color: fontColor,
borderBottomLeftRadius: round ? bBRadius : 0,
borderBottomRightRadius: round ? bBRadius : 0
}"
>
<view
v-if="isBack"
class="back_title"
:style="{
height: customBar - statusBar + 'px',
lineHeight: customBar - statusBar + 'px',
position: 'fixed',
top: statusBar + 'px',
left: '20rpx',
boxSizing: 'border-box',
}"
>
<text
v-if="needBackIcon"
:style="{
fontWeight: 600,
zIndex: 9,
display: 'inline-block',
width: iconWidth,
height: customBar - statusBar + 'px',
lineHeight: customBar - statusBar + 'px',
}"
class="iconfont iconxiangzuo"
@click="goBack"
></text>
<slot name="back"></slot>
</view>
<view
:class="{ content: true, is_center: itCenter }"
:style="{
height: customBar + 'px',
paddingTop: statusBar + 'px',
paddingRight: itCenter ? 0 : customPdR + 5 + 'px'
}"
>
<slot name="content"></slot>
</view>
<view class="custom_body">
<slot name="body"></slot>
</view>
</view>
</view>
</template>
<script>
const app = getApp()
export default {
name: 'Custom',
props: {
isBack: {
type: Boolean,
default: true,
},
// 是否需要返回按钮
needBackIcon: {
type: Boolean,
default: true,
},
// 是否需要下面为圆角
round: {
type: Boolean,
default: false,
},
bBRadius: {
type: String,
default: '50%',
},
bgColor: {
type: String,
default: '#fff',
},
bgImage: {
type: String,
default: '',
},
fontColor: {
type: String,
default: '#000',
},
heightSize: {
type: String,
default: '',
},
// 是否需要占位
needSeat: {
type: Boolean,
default: true,
},
// 点击返回按钮是否是返回上一页
backLastPage: {
type: Boolean,
default: true,
},
// 是否居中
itCenter: {
type: Boolean,
default: true
},
iconWidth: {
type: String,
default: '100rpx',
}
},
data() {
return {
customBar: app.globalData.customBar,
statusBar: app.globalData.statusBar,
customPdR: app.globalData.customPdR
}
},
mounted() {
this.customBar = app.globalData.customBar
this.statusBar = app.globalData.statusBar
this.customPdR = app.globalData.customPdR
},
methods: {
goBack() {
if (this.backLastPage) {
uni.navigateBack({
delta: 1,
})
} else {
this.$emit('back')
}
},
},
}
</script>
<style lang="scss" scoped>
@import url('~@/static/iconfont.css');
.custom_bar {
width: 100vw;
.custom {
box-sizing: border-box;
display: flex;
flex-direction: column;
width: 100vw;
background-size: cover;
&.round {
border-bottom-right-radius: 16rpx;
border-bottom-left-radius: 16rpx;
}
&.is_fixed {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 99;
}
.back_title {
z-index: 100;
display: flex;
align-items: center;
width: 100%;
}
.content {
position: fixed;
top: 0;
right: 0;
left: 0;
box-sizing: border-box;
width: 100%;
font-weight: 600;
display: flex;
align-items: center;
}
.is_center {
justify-content: center;
}
.custom_body {
flex: 1;
width: 100%;
position: relative;
}
}
}
</style>
App.vue
<script lang="ts">
import { defineComponent } from "vue"
export default defineComponent<any>({
globalData: {
statusBar: 0,
customBar: 0,
customPdR: 0,
custom: {}
},
onLaunch() {
console.log("App Launch")
// 获取小程序信息
let count = 0
const getSystem = () => {
if (count === 3) return
count += 1
uni.getSystemInfo({
success: (res: any) => {
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.globalData.statusBar = res.statusBarHeight // 状态栏高度
if (menuButtonInfo) {
this.globalData.custom = menuButtonInfo // 胶囊信息
this.globalData.customBar = menuButtonInfo.bottom + menuButtonInfo.top - res.statusBarHeight // 自定义导航栏总高度
this.globalData.customPdR = res.windowWidth - menuButtonInfo.right + menuButtonInfo.width // 胶囊按钮与右侧的距离
} else {
this.globalData.customBar = res.statusBarHeight + 40
}
},
fail: () => {
getSystem()
},
})
}
getSystem()
},
onShow() {
console.log("App Show")
},
onHide() {
console.log("App onHide")
}
})
</script>
<style></style>