前言
做移动端项目时为了兼容各种手机型号的界面,最好有一个统一的页面组件对样式做统一处理,例如:判断是否显示状态栏,是否显示头部导航,是否空出底部区域等等,本篇会带大家从零到一开发一个 uniapp 的通用页面组件
需求
本次开发的页面,组件,需要完成以下功能
- 可配置控制是否显示原生导航,显示状态栏,并且也可以控制状态栏颜色
- 可配置控制是否留出底部固定区域
开发
初始化页面数据
- 编写页面组件类,获取系统配置,初始化样式数据
class Page { constructor() { this.system = uni.getSystemInfoSync() this.init() } init = () => { console.log(this.system); } } export default Page 复制代码
- 页面组件基本结构
<template> <view class="sf-page" :class="theme"> <!-- 页面头部 --> <template v-if="customHeader"> <view class="sf-page-header"> <!-- 头部核心 --> <slot name="header"></slot> </view> </template> <!-- 页面主体 --> <view class="sf-page-body"> <slot name="body"></slot> </view> <!-- 页面底部 --> <template v-if="customFooter"> <view class="sf-page-footer"> <slot name="footer"></slot> </view> </template> </view> </template> <script setup> import { computed, toRefs } from "vue" import Page from './class/page.js' const props = defineProps({ customHeader: { type: Boolean, default: false }, customFooter: { type: Boolean, default: false }, }) const page = new Page() const theme = computed(() => { return uni.$theme.get() }) </script> <style> .sf-page { min-height: 100vh; width: 100%; } .sf-page-header { position: fixed; top: 0; left: 0; right: 0; background-color: #ffffff; z-index: 99; } .sf-page-body { } .sf-page-footer { position: fixed; bottom: 0; left: 0; right: 0; background-color: #ffffff; z-index: 99; } </style> 复制代码
实现状态栏与底部配置
- 通过系统
api
,获取系统状态栏高度
import { ref } from 'vue' class Page { constructor() { this.system = uni.getSystemInfoSync() this.statusBarHeight = 0 this.headerHeight = 45 this.footerHeight = 45 this.init() } init = () => { this.statusBarHeight = this.system.statusBarHeight } } export default Page 复制代码
- 页面组件配置
<template> <view class="sf-page" :class="theme"> <!-- 页面头部 --> <template v-if="customHeader"> <view class="sf-page-header"> <!-- 沉浸式状态栏 --> <view :style="{ height: statusBarHeight + 'px', background: statusBarBG }"></view> <!-- 头部核心 --> <view :style="{ height: headerHeight + 'px' }"> <slot name="header"></slot> </view> </view> <!-- 占位 --> <view :style="{ height: statusBarHeight + headerHeight + 'px' }"></view> </template> <!-- 页面主体 --> <view class="sf-page-body"> <slot name="body"></slot> </view> <!-- 页面底部 --> <template v-if="customFooter"> <view class="sf-page-footer"> <slot name="footer"></slot> </view> </template> </view> </template> <script setup> import { computed, toRefs } from "vue" import Page from './class/page.js' const props = defineProps({ customHeader: { type: Boolean, default: false }, customFooter: { type: Boolean, default: false }, statusBarBG: { type: String, default: 'none' } }) const page = new Page() const { headerHeight, statusBarHeight, footerHeight } = toRefs(page) const theme = computed(() => { return uni.$theme.get() }) </script> 复制代码
页面组件实例化Page
对象,这里注意解构高度属性时,需要使用toRefs
实现响应式, 这样,即可通过 customHeader,customFooter
控制相应区域是否显示,并且根据设置的 height
来控制对应区域的高度, 也可通过 statusBarBG
控制状态栏的颜色
<sf-page :customHeader="true" :customFooter="false" statusBarBG="#333333"> </sf-page> 复制代码
页面使用
<sf-page :customHeader="true" :customFooter="true" statusBarBG="#333333"> <template v-slot:header> <view class=""> // ... 导航 </view> </template> <template v-slot:body> <view class="main"> // ... 内容 </view> </template> <template v-slot:footer> <view class=""> // ... 底部操作 </view> </template> </sf-page> 复制代码
这样,就可以根据设计稿的需要,动态的控制是否显示头部导航或底部操作区域