Taro小程序自定义导航栏
navigationStyle: 'custom'
nav-bar.tsx
import React, { forwardRef, Ref, useEffect, useImperativeHandle, useState } from 'react'
import { View, Text, Image } from '@tarojs/components'
import Taro from '@tarojs/taro';
import './nav-bar.less'
const backIcon = 'data:image/png;base64,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'
interface NavBarProps {
title: string;
children?: React.ReactNode;
showBack?: boolean;
}
export interface NavBarRef {
/**
* 导航栏高度
*/
navHeight: number;
}
function NavBar(props: NavBarProps, ref: Ref<NavBarRef>) {
const { title, children, showBack = true } = props;
const [navHeight, setNavHeight] = useState(0)
const [navPaddingRight, setNavPaddingRight] = useState(0)
const [navPaddingLeft, setNavPaddingLeft] = useState(0)
const [navPaddingTop, setNavPaddingTop] = useState(0)
const [leftWidth, setLeftWidth] = useState(0)
const [leftHeight, setLeftHeight] = useState(0)
useImperativeHandle(ref, () => ({
navHeight,
}), [navHeight])
useEffect(() => {
// 计算导航栏高度
const systemInfo = Taro.getWindowInfo(); // 获取系统信息
const menuButtonInfo = Taro.getMenuButtonBoundingClientRect(); // 获取胶囊信息
const statusBarHeight = systemInfo.statusBarHeight || 0; // 状态栏高度
const menuButtonHeight = menuButtonInfo.height; // 胶囊高度
const menuButtonTop = menuButtonInfo.top; // 胶囊top
const menuButtonRight = menuButtonInfo.right; // 胶囊right
const navBarHeight = statusBarHeight + menuButtonHeight + (menuButtonTop - statusBarHeight) * 2; // 导航栏高度
const paddingRight = systemInfo.screenWidth - menuButtonRight; // 导航栏右侧padding
const paddingTop = statusBarHeight; // 导航栏上边padding
setNavHeight(navBarHeight)
setNavPaddingLeft(paddingRight)
setNavPaddingRight(paddingRight + menuButtonInfo.width)
setNavPaddingTop(paddingTop)
setLeftWidth(menuButtonInfo.width)
setLeftHeight(menuButtonInfo.height)
}, [])
return (
<View className='nav_bar'
style={{
height: navHeight + 'px',
paddingRight: navPaddingRight + 'px',
paddingLeft: navPaddingLeft + 'px',
paddingTop: navPaddingTop + 'px'
}}
>
<View
className='back'
style={{
width: leftWidth + 'px',
height: leftHeight + 'px',
}}
>
{
showBack && <Image src={backIcon} className='back_icon' />
}
</View>
<View className='middle'>
{
title ? <Text className='title'>{title}</Text> : children
}
</View>
</View>
)
}
export default forwardRef(NavBar)nav-bar.less
.nav_bar {
position: fixed;
width: 100%;
display: flex !important;
align-items: center;
box-sizing: border-box;
background-color: white;
z-index: 999;
.back {
display: flex;
align-items: center;
border-radius: 999px;
background-color: white;
font-size: 28px;
color: #333;
.back_icon {
width: 40px;
height: 40px;
}
}
.middle {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
.title {
font-size: 32px;
font-weight: bold;
color: black;
}
}
}
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果