使用mobx-miniprogram构建store
screenStore.js代码
import { observable, action } from "mobx-miniprogram";
export const screenStore = observable({
statusBarHeight: 0, // 状态栏高度
navBarHeight: 0, // 自定义导航栏高度
safeHeight: 0, // 屏幕安全区域高度
bottomSafeHeight: 0, // 底部安全区域高度
menuRight: 0, // 胶囊按钮右侧到屏幕右边的间距
menuHeight: 0, // 胶囊按钮高度
initData: action(function () {
const windowInfo = wx.getWindowInfo();
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
this.statusBarHeight = windowInfo.statusBarHeight;
this.navBarHeight = menuButtonInfo.height + (menuButtonInfo.top - this.statusBarHeight) * 2;
this.safeHeight = windowInfo.safeArea.height;
this.bottomSafeHeight = windowInfo.screenHeight - windowInfo.safeArea.height - this.statusBarHeight;
this.menuRight = windowInfo.screenWidth - menuButtonInfo.right;
this.menuHeight = menuButtonInfo.height;
})
})
使用behaviors在组件和页面中自动引入
screenBehavior.js代码
import { BehaviorWithStore } from 'mobx-miniprogram-bindings';
import { screenStore } from '../screenStore';
export const screenBehavior = BehaviorWithStore({
storeBindings: {
store: screenStore,
fields: ['statusBarHeight', 'navBarHeight', 'safeHeight', 'bottomSafeHeight', 'menuRight', 'menuHeight'],
actions: ['initData']
}
});
在app.js中初始化
import { screenStore } from "@/stores/screenStore"
App({
onLaunch() {
screenStore.initData()
}
})
screen-header组件代码
wxml部分
<view
class="page_header"
style="height: {{navBarHeight + statusBarHeight}}px;padding: {{statusBarHeight}}px {{menuRight}}px 0;{{backgroundColor}};box-shadow: {{boxShadow}};align-items: {{alignItems}};"
>
<view class="page_header_left">
<view class="back" wx:if="{{canBack}}" bind:tap="goBack">
<image src="{{imgURL}}/icon/icon-arrow-left-black.svg" mode="widthFix" />
<text class="title">{{title}}</text>
</view>
<slot name="left"></slot>
</view>
<view class="page_header_center">
<slot name="center"></slot>
</view>
<view class="page_header_right">
<slot name="right"></slot>
</view>
</view>
css部分
.page_header {
display: flex;
justify-content: space-between;
width: 100vw;
box-sizing: border-box;
&_left {
display: flex;
align-items: center;
gap: 16rpx;
flex: 1;
.back {
display: flex;
align-items: center;
gap: 16rpx;
image {
width: 18rpx;
height: 34rpx;
}
.title {
font-size: 34rpx;
font-weight: 500;
line-height: normal;
letter-spacing: 0;
color: #333333;
}
}
}
&_right {
flex: 1;
}
}
js部分
import { imgURL } from '@/utils/env'
import { screenBehavior } from '@/stores/behaviors/screenBehavior';
Component({
behaviors: [screenBehavior],
options: {
multipleSlots: true
},
properties: {
backgroundColor: {
type: String,
value: '#FFFFFF'
},
alignItems: {
type: String,
value: 'center'
},
boxShadow: {
type: String,
value: '0 0 2px 0 rgba(0, 0, 0, 0.3)'
},
canBack: {
type: Boolean,
value: false
},
title: {
type: String,
value: ''
}
},
data: {
imgURL
},
methods: {
goBack() {
const pages = getCurrentPages(); // 获取当前页面栈
const currentPageStackLength = pages.length;
if (currentPageStackLength > 1) {
// 存在上一页,返回上一层
wx.navigateBack({
delta: 1
});
} else {
// 没有上一页,跳转至首页 (假设首页路径为 '/pages/index/index')
wx.reLaunch({
url: '/pages/home/index'
});
}
}
}
})
json无需修改
screen-bottom组件代码
wxml部分
<view class="page_bottom" style="height:{{bottomSafeHeight}}px;"></view>
css 部分
.page_bottom {
width: 100vw;
background-color: #fff;
}
js部分
import { screenBehavior } from '@/stores/behaviors/screenBehavior';
Component({
behaviors: [screenBehavior],
options: {
multipleSlots: true
},
properties: {
},
data: {
},
methods: {
}
})
json无需修改
在页面中引用
{
"usingComponents": {
"screen-header": "/components/screen-header",
"screen-bottom": "/components/screen-bottom"
}
}
<view class="page">
<screen-header canBack boxShadow="none" />
<view class="page_content"></view>
<screen-bottom />
</view>