運用Taro實現多端導航欄/tabbar實例 (H5 + 小程式 + React Native) 最近一直在搗鼓taro開發,雖說官網介紹支持編譯到多端,但是網上大多數實例都是H5、小程式,很少有支持RN端。恰好Taro是基於React技術,想著之前也做過一些react項目,如是抱著好奇深究了一番, ...
運用Taro實現多端導航欄/tabbar實例 (H5 + 小程式 + React Native)
最近一直在搗鼓taro開發,雖說官網介紹支持編譯到多端,但是網上大多數實例都是H5、小程式,很少有支持RN端。恰好Taro是基於React技術,想著之前也做過一些react項目,如是抱著好奇深究了一番,採坑了不少,尤其是編譯到RN時樣式問題。
如上圖:分別在H5、小程式、RN端運行效果
◆ Taro引入阿裡字體圖標Iconfont
在進行下文介紹之前,先簡單介紹下taro字體圖標的使用,如果你項目中有引入Taro-UI,直接使用taro-ui圖標即可
詳情看 taro-ui圖標
下載好阿裡字體圖標後,複製fonts文件夾到項目下,如下圖放在:styles目錄下,並將iconfont.css複製一份改為iconfont.scss
引入: import './styles/fonts/iconfont.scss'
在h5、小程式下 這種寫法即可: <Text className="iconfont icon-back"></Text>
不過為了相容RN,只能通過Unicode方式這樣寫: <Text className="iconfont"></Text>
如果是通過變數傳遞: let back = '\ue84c' <Text>{back}</Text>
◆ 自定義導航欄Navbar
在項目根目錄App.js裡面 配置navigationStyle,將其設置為custom,此時就進入自定義導航欄模式
class App extends Component { config = { pages: 'pages/index/index', ... ], window: { backgroundTextStyle: 'light', navigationBarBackgroundColor: '#fff', navigationBarTitleText: 'Taro', navigationBarTextStyle: 'black', navigationStyle: 'custom' }, ... } ... }
在components目錄下新建導航欄Navbar組件
import Taro from '@tarojs/taro' import { View, Text, Input, Image } from '@tarojs/components' import classNames from "classnames"; import './index.scss' export default class NavBar extends Taro.Component { // 預設配置 static defaultProps = { isBack: false, leftIcon: '\ue84c', title: ' ', background: '#6190e8', color: '#fff', center: false, search: false, searchStyle: '', fixed: false, headerRight: [], } constructor(props) { super(props) this.state = { searchText: '', } } ... render() { const { isBack, leftIcon, title, background, color, center, search, searchStyle, fixed, height, headerRight } = this.props const { searchText } = this.state let weapp = false if (process.env.TARO_ENV === 'weapp') { weapp = true } return ( <View className={classNames('taro__navbar', fixed && 'taro__navbar--fixed', fixed && weapp && 'taro__navbar-weapp--fixed')}> <View className={classNames('taro__navbar-wrap', fixed && 'taro__navbar-wrap--fixed', weapp && 'taro__navbar-wrap__weapp')} style={{backgroundColor: background}}> {/* 返回 */} <View className={classNames('taro__navbar-left__view', isBack && 'taro__navbar-left__view--isback')}> {isBack && <TouchView activeOpacity={.5} onClick={this.handleNavigateBack}> <View className="taro__navbar-icon__item"><Text className="iconfont taro__navbar-iconfont" style={{color: color}}>{leftIcon}</Text></View> </TouchView> } </View> {/* 標題 */} {!search && center && !weapp ? <View className="flex1" /> : null} {search ? ( <View className="taro__navbar-search flex1"> <Input className="taro__navbar-search__input" placeholder="搜索..." onInput={this.updateInputText} style={{color: color, ...searchStyle}} /> </View> ) : ( <View className={classNames('taro__navbar-title flex1', center && !weapp && 'taro__navbar-title--center')}> {title && <Text className="taro__navbar-title__text" style={{color: color}}>{title}</Text>} </View> ) } {/* 右側 */} <View className="taro__navbar-right__view"> {headerRight.map((item, index) => ( <TouchView activeOpacity={.5} key={index} onClick={()=>item.onClick && item.onClick(searchText)}> <View className="taro__navbar-icon__item"> {item.icon && <Text className="iconfont taro__navbar-iconfont" style={{color: color, ...item.style}}>{item.icon}</Text>} {item.text && <Text className="taro__navbar-iconfont__text" style={{color: color, ...item.style}}>{item.text}</Text>} {item.img && <Image className="taro__navbar-iconfont__img" src={item.img} mode='aspectFit' />} {/* 圓點 */} {!!item.badge && <Text className="taro__badge taro__navbar-badge">{item.badge}</Text>} {!!item.dot && <Text className="taro__badge-dot taro__navbar-badge--dot"></Text>} </View> </TouchView> )) } </View> </View> </View> ); } }
在頁面引入組件即可: import NavBar from '@components/navbar'
引入方式有兩種:
// index/index.js 首頁 import NavBar from '@components/navbar' class Index extends Component { config = { navigationBarTitleText: '首頁', usingComponents: { 'navbar2': '../../components/navbar', // 書寫第三方組件的相對路徑 }, } render () { return ( <View className='index'> { /* 方法一 */ } <NavBar /> { /* 方法二 */ } <navbar2 /> ... </View> ) } }
支持自定義背景、顏色、左側圖標、標題居中、搜索框,右側按鈕支持圖標/文字/圖片,還可以設置樣式,紅點提示、事件處理
<NavBar title='Taro標題欄' fixed headerRight={[ {icon: '\ue614', style: {color: '#e93b3d'}}, {img: require('../../assets/taro.png'), dot: true, onClick: this.handleCallback}, {icon: '\ue600', style: {marginRight: 10}}, ]} />
<NavBar isBack leftIcon={'\ue69f'} title='搜索欄' background='#42b983' color='#fcc' search searchStyle={{ backgroundColor:'rgba(255,255,255,.6)', borderRadius: Taro.pxTransform(50), color: '#333' }} headerRight={[ {icon: '\ue622', style: {color: '#6afff9'}}, {icon: '\ue63a'}, ]} />
<NavBar isBack leftIcon={'\ue84f'} title='查找' background='#545454' color='#fff' headerRight={[ {img: require('../../assets/default-avatar.png'), dot: true}, {text: '添加朋友', style: {color: '#15e413'}}, ]} />
◆ 自定義底部Tabbar菜單
如果在App.js裡面沒有配置tabbar,則可以自定義底部,如下圖在三端下效果
同樣在components目錄下新建tabbar組件
import Taro from '@tarojs/taro' import { View, Text } from '@tarojs/components' import classNames from 'classnames' import './index.scss' export default class TabBar extends Taro.Component { // 預設參數配置 static defaultProps = { current: 0, background: '#fff', color: '#999', tintColor: '#6190e8', fixed: false, onClick: () => {}, tabList: [] } constructor(props) { super(props) this.state = { updateCurrent: props.current } } ... render() { const { background, color, tintColor, fixed } = this.props const { updateCurrent } = this.state return ( <View className={classNames('taro__tabbar', fixed && 'taro__tabbar--fixed')}> <View className={classNames('taro__tabbar-list', fixed && 'taro__tabbar-list--fixed')} style={{backgroundColor: background}}> {this.props.tabList.map((item, index) => ( <View className="taro__tabbar-item taro__tabbar-item--active" key={index} onClick={this.updateTabbar.bind(this, index)}> <View className="taro__tabbar-icon"> <Text className="iconfont taro__tabbar-iconfont" style={{color: updateCurrent == index ? tintColor : color}}>{item.icon}</Text> {/* 圓點 */} {!!item.badge && <Text className="taro__badge taro__tabbar-badge">{item.badge}</Text>} {!!item.dot && <Text className="taro__badge-dot taro__tabbar-badge--dot"></Text>} </View> <Text className="taro__tabbar-title" style={{color: updateCurrent == index ? tintColor : color}}>{item.title}</Text> </View> ))} </View> </View> ); } }
自定義tabbar也支持自定義背景、顏色、圖標,點擊選項事件返回索引值
<TabBar current={currentTabIndex} background='#f8f8f8' color='#999' tintColor='#6190e8' fixed onClick={this.handleTabbar} tabList={[ {icon: '\ue627', title: '首頁', badge: 8}, {icon: '\ue61e', title: '商品'}, {icon: '\ue605', title: '個人中心', dot: true}, ]} />
// tabbar事件
handleTabbar = (index) => { this.setState({currentTabIndex: index}) }
emmmm~~~,到這裡就介紹差不多了,後續會考慮使用Taro技術開發個h5/小程式/RN端實戰項目。