移动端项目组件封装及版本介绍

react-native开发常用组件封装

rn项目中各个技术版本:
最新版本:21年3月发布 0.64
工作中使用的是公司封装的rn,基于rn框架封装了路由 及redux的实现,并封装好用的创建页面的组件
(有些组件使用ant-mobile封装的组件,例如Checkbox, DatePicker, List, Picker等 https://antd-mobile-v2.surge.sh/index-cn, 就是ant design mobile 中RN的组件库,具体版本看项目中引入的版本 package.json中看然后选择对应的版本 https://3x.rn.mobile.ant.design/components/checkbox-cn/)

RN+antd-mobile+ramda

1、单选Radio的封装 (可以用组件库中的Radio)
重点看选中的样式:当点击时更新选中项的答案,触发重新渲染的逻辑,让选中项的样式为中间带实心圆

                 <KeyboardAwareScrollView>
                        {
                           questionOptionList.map((item, index) => {
                             const {
                               question, // 问题
                               optionList = [], // 选项数组
                               answer = 1, // 有的话就是该值,没有的话就是默认值1,初次登陆没有值
                              } = item;
                             const touchStyle = [styles.yesView, styles.yesColor];   
                             const btnStyle = styles.yesBtn;
                             const centerStyle = styles.yesCenter;// 中间小点点
                             const textStyle = styles.yesText;

                             return (
                               // 问题渲染
                              <View style={styles.questionContainer} key={index}>
                                 <View style={styles.questionView}>
                                   <Text style={styles.questionText}>{`${index + 1}${question}`}</Text>
                                   {
                                     item.description ? (
                                       <TouchableOpacity
                                         activeOpacity={0.5}
                                         onPress={() => this.questionAlert(true, item.description)}
                                       >
                                         <Image source={PImageSet.editIntro} style={styles.change}/>
                                       </TouchableOpacity>
                                     )
                                     : null
                                   }
                                 </View>
                                 <View style={styles.answerView}>
                                   {
                                     // 问题答案渲染
                                     optionList.map((x, idx) => (
                                       <TouchableOpacity
                                         style={touchStyle}
                                         onPress={() => this.checkAnswer(index, x.key)}
                                         activeOpacity={1}
                                       >

                                         <View style={btnStyle}>
                                           {
                                              answer === x.key ? (
                                                <View style={centerStyle}/>
                                              ) : null
                                            }
                                         </View>
                                         <Text style={textStyle}>{x.value}</Text>
                                       </TouchableOpacity>
                                      ))
                                  }
                              </View>
                          </View>
                             );
                           })
                         }
                      </KeyboardAwareScrollView>                 
yesView: {
    justifyContent: 'flex-start',
    alignItems: 'center',
    flexDirection: 'row',
    // width: 80,
    height: 32,
    borderRadius: 3,
    paddingLeft: px(30),
    paddingRight: px(30),
  },
  yesColor: {
    backgroundColor: 'rgba(60, 90, 250, 0.1)',
  },
  yesBtn: { 外面小圆圈⭕️ ,不填背景色就是空圆
    width: 16,
    height: 16,
    borderWidth: 1,
    borderRadius: 10,
    borderColor: '#4c83ff',
    borderStyle: 'solid',
    justifyContent: 'center',
    alignItems: 'center',
  },
  yesCenter: { // 中间小点点
    width: 8,
    height: 8,
    borderRadius: 4,
    backgroundColor: '#4c83ff',
  },
  yesText: {
    marginLeft: 5,
    color: '#4c83ff',
  },
  questionContainer: {
    marginTop: px(25),
    paddingLeft: 20,
  },
  questionView: {
    width: ScreenWidth,
    flexDirection: 'row',
  },
  questionText: {
    color: '#333',
  },
  answerView: {
    margin: px(10),
    flexDirection: 'column',
  },
  noticeText: {
    marginLeft: 20,
    marginTop: px(20),
    color: '#ff0000'
  },
  change: {
    width: 17,
    height: 17,
    marginLeft: 5,
  },

2、多选checkbox的封装(可选择1或多个, 使用ant mobile中RN)

// 多用于数组的遍历渲染选框,用时查官网
         <CheckboxItem
            checked={this.state.checkboxItem1}
            onChange={event => {
              this.setState({ checkboxItem1: event.target.checked });
            }}
          >
            Option 1
          </CheckboxItem>
          <CheckboxItem>Option 2</CheckboxItem>
          <CheckboxItem disabled>Option 3</CheckboxItem>
          <CheckboxItem disabled checked>
            Option 4
          </CheckboxItem>

3、下拉选项的封装实现(类似select)

import React, { Component, PropTypes } from 'react';
import { Text, View, Picker, StyleSheet } from 'react-native';
import { px } from 'BizStyle';

const styles = StyleSheet.create({
  container: {
    display:'flex',
    fontSize: px(26),
    flexDirection: 'row',
  },
  select: {
    height: px(40),
    fontSize: px(26),
    textAlign: 'center',
    borderColor: '#FFF',
    borderWidth: 1,
    borderStyle: 'solid',
    width: px(450),
  },
  label: {
    height: px(40),
    fontSize: px(26),
  },
  labelText:{
    color:'#F00'
  },
});
/**
 *  基于Picker 创建的Select 组件
 *  必传参数只有 下拉列表的数据 list
 */
export default class Select extends Component {
  static propTypes = {
    selected: PropTypes.string,
    onChange: PropTypes.func,
    list: PropTypes.array,
    text: PropTypes.string,
  };

  static defaultProps = {
    selected: '',
    onChange: () => {},
    list: [],
    text: '',
  };

  constructor(props) {
    super(props);
    const { selected } = props;
    this.state = {
      selected,
    };
  }
  onChange = (val) => {
    const item = this.props.list.find(e => e.value === val);
    this.setState({
      selected: val,
    });
    this.props.onChange(item);
  }
  render() {
    const { list = [], text } = this.props;
    const { selected } = this.state;
    return (
      <View style={styles.container}>
        {
          text ? 
           <View  style={styles.label}>
              <Text style={styles.labelText}>{text}</Text>
           </View>
           : null
        }
        <Picker
          selectedValue={selected}
          style={styles.select}
          onValueChange={itemValue => this.onChange(itemValue)}
          mode="dropdown"
          prompt={'选择类型'}
        >
          {
            list.map((item, index) =>
              <Picker.Item label={item.label} value={item.value} key={index} />)
          }
        </Picker>
      </View>
    );
  }
}

4、日期组件的封装实现(用RN原生组件,是在底部弹出的。或者使用ant mobile中的DatePicker组件)

   // 使用
         <List>
            <DatePicker
              value={this.state.value}  // 绑定值
              mode="datetime"
              defaultDate={new Date()}
              minDate={new Date(2015, 7, 6)}
              maxDate={new Date(2026, 11, 3)}
              onChange={this.onChange}
              format="YYYY-MM-DD"
            >
              <List.Item arrow="horizontal">开始时间</List.Item>   // 日期按钮前展示的内容
            </DatePicker>
          </List>

在这里插入图片描述
5、弹框提示的实现(ToolTip、Alert)

6、二次确认弹框的实现(简单提示文案,没有复杂的操作。有些需要考虑弹框有输入框等操作时情况)

// 使用react-native中的View Text封装
import React, { PropTypes } from 'react';
import {
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
} from 'react-native';

const styles = StyleSheet.create({
  contain: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    top: 0,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    justifyContent: 'center',
  },
  load: {
    marginHorizontal: 32.5,
    backgroundColor: '#FFFFFF',
    borderRadius: 4,
  },
  title: {
    height: 60,
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
  },
  titleText: {
    color: '#1E2C32',
    fontSize: 18,
    fontWeight: '500',
  },
  loadAction: {
    flexDirection: 'row',
    alignItems: 'center',
    height: 50,
    borderColor: '#DDDDDD',
    borderTopWidth: 1,
  },
  basicAction: {
    height: 50,
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  basicActionText: {
    fontSize: 18,
    color: '#7095F5',
  },
  line: {
    position: 'absolute',
    left: 0,
    top: 0,
    bottom: 0,
    width: 0.5,
    backgroundColor: '#DDDDDD',
  },
  content: {
    marginHorizontal: 18,
    marginBottom: 25,
  },
  contentText: {
    color: '#888888',
    fontSize: 15,
    lineHeight: 20,
  },
});

const Action = ({ style, text, action, line = false }) => (
  <TouchableOpacity
    onPress={action}
    style={[styles.basicAction, style]}
  >
    {line ? <View style={styles.line}/> : null}
    <Text style={[styles.basicActionText, text === '取消' ? { color: '#000000' } : {}]}>
      {text}
    </Text>
  </TouchableOpacity>
);

Action.propTypes = {
  style: PropTypes.object,
  text: PropTypes.string,
  action: PropTypes.func,
  line: PropTypes.bool,
};

const EditAlert = ({
  title,
  style,
  cancel,
  cancelText,
  sure,
  sureText,
  content,
  contentStyle
}) => (
  <View style={[styles.contain, style]}>
    <View style={styles.load}>
      <View style={styles.title}>
        <Text style={styles.titleText}>{title}</Text>
      </View>

      {
        content ? (
          <View style={[styles.content, content.length > 30 ? {} : { alignItems: 'center' }]}>
            <Text style={[styles.contentText, contentStyle]}>{content}</Text>
          </View>
        ) : null
      }

      <View style={styles.loadAction}>
        <Action text={cancelText} action={cancel}/>
        {sure ? <Action text={sureText} action={sure} line/> : null}
      </View>
    </View>
  </View>
);

EditAlert.propTypes = {
  title: PropTypes.string,   // 弹框标题
  style: View.propTypes.style, // 弹框整体容器样式
  contentStyle: Text.propTypes.style, // 内容区提示文本样式
  cancel: PropTypes.func, // 取消按钮的回调函数,主要用于取消弹框的显示
  cancelText: PropTypes.string, // 取消按钮展示的文字
  sure: PropTypes.func, // 确认回调函数,用于处理提交的逻辑及弹框消失
  sureText: PropTypes.string, // 确认按钮显示的文字
  content: PropTypes.string, // 内容区展示的文案
};

EditAlert.defaultProps = {
  title: 'alert',
  style: {},
  contentStyle: {},
  cancel: () => {
  },
  cancelText: '取消',
  sure: null,
  sureText: '确认',
  content: null,
};

export default EditAlert;

// 项目中使用案例
            <EditAlert
              title="提示"
              content={alertContent}
              cancel={() => this.cancel(false)}
              sure={this.submit}
              cancelText={'返回'}
              sureText={'确认'}
              contentStyle={{ color: '#f12345' }}
            />

7、按钮的实现(利用Text实现,用TouchableOpacity组件包,可以实现触摸点击事件及点击时透明度变化的效果。原生组件中的Button样式固定,不美观)

                    <View>
                      <TouchableOpacity
                        onPress={this.updateSubmitAlert} // 按钮点击后的功能,例如显示二次弹框或调用接口传数据
                        style={styles.submitBtnWrapper}
                        disabled={false}
                        accessible
                      >
                        <Text style={styles.submitTxt}>  // 设置字体和文字颜色
                          提交
                        </Text>
                      </TouchableOpacity>
                    </View>
                 submitBtnWrapper: { // 按钮整体样式
				    position: 'absolute',
				    left: 10,
				    right: 10,
				    height: 50,
				    bottom: 65,
				    borderRadius: 5,
				    backgroundColor: '#82A0FA',
				    alignItems: 'center',
				    justifyContent: 'center'
				  },   

备注:一般公司项目中会使用RN原生组件、基于原生组件封装的组件库 RNX-UI、antd-mobile组件库

React Native 版本
0.63之前
0.63-0.69

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值