V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaoyan2017
V2EX  ›  推广

Taro+React 自定义导航栏/tabbar 组件|基于 Taro 多端实践

  •  
  •   xiaoyan2017 · 2019-11-26 23:50:59 +08:00 · 2290 次点击
    这是一个创建于 1584 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于 Taro 实现多端自定义导航栏+Tabbar 组件实例 (H5 + 小程序 + React Native)

    最近一直学习 taro 框架,官方的介绍 Taro 是一套遵循 React 语法规范的 多端开发 解决方案。使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信 /百度 /支付宝 /字节跳动 /QQ 小程序、快应用、H5、React-Native 等)运行的代码。

    但是提供的大多都是 H5、小程序端项目,至于 RN 端实例相当甚少,如是只有自己深究一番,毕竟之前有过 React 及 reactNative 项目经验,如是便有了这篇Taro 自定义 Navbar+Tabbar 组件

    如下图:H5+小程序+RN 端效果图

    • Taro 引入阿里字体图标 Iconfont

    下载阿里字体图标,复制 fonts 文件夹到项目下,如下图放在:styles 目录下,并将 iconfont.css 复制一份改为 iconfont.scss 引入图标:import './styles/fonts/iconfont.scss'

    h5、小程序下 这种写法即可: <Text className="iconfont icon-back"></Text>

    不过为了兼容 RN,只能通过 Unicode 方式这样写:<Text className="iconfont">&#xe84c;</Text>

    通过变量传递:let back = '\ue84c' <Text>{back}</Text>

    • Taro 自定义导航栏 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'
            },
            ...
        }
        
        ...
    }
    

    /*
     * @desc   Taro 自定义导航条 navbar 组件
     * @about  Q:282310962  wx:xy190310
     */
    
    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'

    Navbar 组件支持自定义背景、颜色、标题居中、搜索框,右侧按钮支持图标 /文字 /图片,还可以设置样式,红点提示、事件传递

    <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'},
        ]} 
    />
    

    • Taro 自定义底部导航 Tabbar 组件

    自定义 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 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},
        ]}
    />
    

    emmmmm~~ 今天就介绍到这里吧,后续计划使用 Taro 开发多端项目实例,届时再分享。✍✍

    ReactNative 聊天 APP 实战|仿微信聊天 /朋友圈 /红包界面

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1070 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 104ms · UTC 19:00 · PVG 03:00 · LAX 12:00 · JFK 15:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.