taro官方文档地址先给出:taro-docs.jd.com/taro/docs/R…;
接下来我们要实现的是这个样式的一个自定义导航条:
简单分析一下,要实现这样的导航条就得兼容所有设备,又因为不同设备系统原有得导航栏高度是不同得。注:下文的Taro是框架对wx对象做的二次封装,其api name和小程序官方一致
而小程序官方提供了这样得api:Taro.getSystemInfoSync(),用于获取系统状态栏信息,可以拿到状态栏高度:statusBarHeight
为了让自定义按钮能和小程序自带的胶囊表现一致,所以就需要获取这个胶囊的大小,小程序提供了Taro.getMenuButtonBoundingClientRect()来获取,剩下的就是常规的写界面了,具体实现看下面的完整代码吧
以下代码是基于我们项目中的UI设计实现
import{ PureComponent } from 'react';
import Taro, { getCurrentInstance } from '@tarojs/taro';
import { View, Image, Text } from '@tarojs/components';
import './index.scss';
class NavBar extends PureComponent {
static defaultProps = {
title: null, // 标题
iconSize: 16, // 默认的icon大小,自定义的左侧返回和主页icon
homePath: process.env.HOME_PATH, // 这里我是把项目的首页地址配置到了环境变脸中,方便使用
hideBtns: false, // 是否隐藏左侧按钮
hideHome: false, // 是否隐藏主页按钮
onClickBack: null, // 主页按钮的点击事件
onClickHome: null // 返回按钮的点击事件
};
// 主页按钮的点击事件,再给上层暴露的接口中返回了当前主页路径
handelHomeIcon = () => {
const { homePath, onClickHome } = this.props;
if (onClickHome) {
onClickHome(homePath)
return
}
Taro.reLaunch({url: `/${homePath}`});
};
// 返回按钮的点击事件
handelBackIcon = () => {
const { onClickBack } = this.props;
if (onClickBack) {
onClickBack();
return
};
Taro.navigateBack({delta: 1})
};
render() {
// 获取系统状态栏高度
const { statusBarHeight } = Taro.getSystemInfoSync()
// 获取小程序右上角胶囊的大小
const { height, top } = Taro.getMenuButtonBoundingClientRect();
/*
计算出小程序导航栏的整体高度,这里要加上系统状态栏的高度,
否则小程序顶部内容会顶到状态栏最顶部位置
*/
const navBarHeight = height + (top - statusBarHeight) * 2 + statusBarHeight;
/*
获取当前路劲中的query参数,如果带有页面标题则默认展示query参数中的标题
这是我再项目中做的一些处理
*/
const { params } = getCurrentInstance().router;
const {
title,
iconSize = height / 1.8,
hideBtns,
hideHome
} = this.props;
return (
<View
className="global-navbar"
style={{
height: `${navBarHeight}px`,
paddingTop: `${statusBarHeight}px`
}}
>
<View className="g-nav-content">
{
!hideBtns &&
<View
className="g-nav-c-iconbox"
style={{
borderRadius: `${height}px`,
height: `${height}px`
}}
>
<Image
className="g-nav-c-icon"
mode="aspectFit"
src={require('../../assets/icon/返回.png')}
style={{
height: `${iconSize}px`,
width: `${iconSize}px`,
transform: `translateX(-1px)`
}}
onClick={this.handelBackIcon}
/>
{
!hideHome &&
<>
<View className="fw-divider-column" />
<Image
className="g-nav-c-icon"
mode="aspectFit"
src={require('../../assets/icon/首页.png')}
style={{
height: `${iconSize}px`,
width: `${iconSize}px`
}}
onClick={this.handelHomeIcon}
/>
</>
}
</View>
}
<Text
className={`global-navbar_text ${hideBtns ? 'g-nav-c-title_left' : 'g-nav-c-title_center'}`}
>
{title ?? params.pageTitle}
</Text>
</View>
</View>
)
}
};
export default NavBar