当前位置: 首页 > news >正文

ReactNative 密码生成器实战

效果展示图

在这里插入图片描述

使用插件

  • Formik

    负责表单校验、监听表单提交、数据校验错误信息展示

  • Yup

    负责表单校验规则

分析页面

从上述的展示图我们可以看到的主要元素有:输入框、单选按钮和按钮。其中生成的密码长度不可能很大也不可能为负数和 0,所以我们可以限定密码长度输入框的规则,即密码长度最小 4 位,最大 16 位,所以我们需要进行表单数据校验操作。

因为我们生产的密码包含大小写、数字和特殊字符,所以我们需要有辅助的功能函数来帮我们来支撑业务。而密码生产的业务功能函数可以划分这几个部分:

  • 生成密码字符串

    存放大小写、数字和特殊字符变量,并且判断用户是否勾选了对应的生成条件,例如是否勾选了是否包含小写字母,并且调用创建密码的功能函数

  • 创建密码

    通过用户制定的规则生成对应的密码并返回

  • 重置密码状态

    重置密码生成器中所有数据的状态

构建页面

根据页面分析和页面展示,我们可以首先实现页面的整体搭建和样式名称的定义,具体代码如下:

export default function PasswordCheck() {return (<ScrollView keyboardShouldPersistTaps="handled"><SafeAreaView style={styles.appContainer}><View style={styles.formContainer}><Text style={styles.title}>密码生产器</Text><View style={styles.inputWrapper}><View style={styles.inputColumn}><Text style={styles.heading}>密码长度</Text></View><TextInputstyle={styles.inputStyle}placeholder="Ex. 8"keyboardType="numeric"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包含小写字母</Text><BouncyCheckboxdisableBuiltInStateisChecked={lowerCase}fillColor="#29AB87"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包括大写字母</Text><BouncyCheckboxdisableBuiltInStateisChecked={upperCase}fillColor="#FED85D"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包括数字</Text><BouncyCheckboxdisableBuiltInStateisChecked={numbers}onPress={() => setNumbers(!numbers)}fillColor="#C9A0DC"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包含符号</Text><BouncyCheckboxdisableBuiltInStateisChecked={symbols}fillColor="#FC80A5"/></View><View style={styles.formActions}><TouchableOpacity style={styles.primaryBtn}><Text style={styles.primaryBtnTxt}>生成密码</Text></TouchableOpacity><TouchableOpacity style={styles.secondaryBtn}><Text style={styles.secondaryBtnTxt}>重置</Text></TouchableOpacity></View></View>{isPassGenerated ? (<View style={[styles.card, styles.cardElevated]}><Text style={styles.subTitle}>生成结果:</Text><Text style={styles.description}>长按密码进行复制</Text><Text selectable={true} style={styles.generatedPassword}>{password}</Text></View>) : null}</SafeAreaView></ScrollView>);
}

编写样式

定义好框架后,我们也有对应的样式名称,那么我们就可以逐步实现样式。

const styles = StyleSheet.create({appContainer: {flex: 1,},formContainer: {margin: 8,padding: 8,},title: {fontSize: 32,fontWeight: "600",marginBottom: 15,},subTitle: {fontSize: 26,fontWeight: "600",marginBottom: 2,},description: {color: "#758283",marginBottom: 8,},heading: {fontSize: 15,},inputWrapper: {marginBottom: 15,alignItems: "center",justifyContent: "space-between",flexDirection: "row",},inputColumn: {flexDirection: "column",},inputStyle: {padding: 8,width: "30%",borderWidth: 1,borderRadius: 4,borderColor: "#16213e",},errorText: {fontSize: 12,color: "#ff0d10",},formActions: {flexDirection: "row",justifyContent: "center",},primaryBtn: {width: 120,padding: 10,borderRadius: 8,marginHorizontal: 8,backgroundColor: "#5DA3FA",},primaryBtnTxt: {color: "#fff",textAlign: "center",fontWeight: "700",},secondaryBtn: {width: 120,padding: 10,borderRadius: 8,marginHorizontal: 8,backgroundColor: "#CAD5E2",},secondaryBtnTxt: {textAlign: "center",},card: {padding: 12,borderRadius: 6,marginHorizontal: 12,},cardElevated: {backgroundColor: "#ffffff",elevation: 1,shadowOffset: {width: 1,height: 1,},shadowColor: "#333",shadowOpacity: 0.2,shadowRadius: 2,},generatedPassword: {fontSize: 22,textAlign: "center",marginBottom: 12,color: "#000",},
});

编写对应功能函数

我们完成了页面的布局,接下来就是实现生产密码的功能,我这里拆解成生成密码字符串创建密码重置密码状态三个功能函数,具体的功能函数如下:

/*** 生成密码字符串* @param passwordLength 密码长度*/const generatePasswordString = (passwordLength: number) => {let characterList = ''; // 生产密码的所有相关字符const upperCaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';const lowerCaseChars = 'abcdefghijklmnopqrstuvwxyz';const digitChars = '0123456789';const specialChars = '!@#$%^&*()_+';// 根据用户的选择,把相关字符拼接到characterList中if (upperCase) {characterList += upperCaseChars}if (lowerCase) {characterList += lowerCaseChars}if (numbers) {characterList += digitChars}if (symbols) {characterList += specialChars}const passwordResult = createPassword(characterList, passwordLength)setPassword(passwordResult)setIsPassGenerated(true)}/*** 根据密码总字符串和密码长度生产随机字符串** @param characters 生产密码的所有相关字符* @param passwordLength 密码长度* @returns 生成的随机密码*/const createPassword = (characters: string, passwordLength: number) => {let result = ''for (let i = 0; i < passwordLength; i++) {const characterIndex = Math.round(Math.random() * characters.length)result += characters.charAt(characterIndex)}return result}/*** 密码重置*/const resetPasswordState = () => {setPassword('')setIsPassGenerated(false)setLowerCase(true)setUpperCase(false)setNumbers(false)setSymbols(false)}

表单校验

在简单介绍 React Native 整合 Formik 实现表单校验中我只是简单介绍了Formik的常用的几个属性,而这次我们要使用如下几个属性:

属性类型说明
touched{ [field: string]: boolean }判断表单字符是否已经访问或者修改过
isValidboolean如果没有错误(即错误对象为空),则返回 true,否则返回 false
handleChange(e: React.ChangeEvent) => void主键更新 values[key]对应的值,其中 key 是事件发出输入的名称属性。如果 name 属性不存在,handleChange 将查找输入的 id 属性

具体的代码如下:

<FormikinitialValues={{ passwordLength: "" }}validationSchema={PasswordSchema}onSubmit={(values) => {generatePasswordString(+values.passwordLength);}}
>{({values,errors,touched,isValid,handleChange,handleSubmit,handleReset,}) => (<><View style={styles.inputWrapper}><View style={styles.inputColumn}><Text style={styles.heading}></Text>{touched.passwordLength && errors.passwordLength && (<Text style={styles.errorText}>{errors.passwordLength}</Text>)}</View><TextInputstyle={styles.inputStyle}value={values.passwordLength}onChangeText={handleChange("passwordLength")}placeholder="例如:8"keyboardType="numeric"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包含小写字母</Text><BouncyCheckboxdisableBuiltInStateisChecked={lowerCase}onPress={() => setLowerCase(!lowerCase)}fillColor="#29AB87"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包括大写字母</Text><BouncyCheckboxdisableBuiltInStateisChecked={upperCase}onPress={() => setUpperCase(!upperCase)}fillColor="#FED85D"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包括数字</Text><BouncyCheckboxdisableBuiltInStateisChecked={numbers}onPress={() => setNumbers(!numbers)}fillColor="#C9A0DC"/></View><View style={styles.inputWrapper}><Text style={styles.heading}>是否包含符号</Text><BouncyCheckboxdisableBuiltInStateisChecked={symbols}onPress={() => setSymbols(!symbols)}fillColor="#FC80A5"/></View><View style={styles.formActions}><TouchableOpacitydisabled={!isValid}style={styles.primaryBtn}onPress={() => handleSubmit()}><Text style={styles.primaryBtnTxt}>生成密码</Text></TouchableOpacity><TouchableOpacitystyle={styles.secondaryBtn}onPress={() => {handleReset();resetPasswordState();}}><Text style={styles.secondaryBtnTxt}>重置</Text></TouchableOpacity></View></>)}
</Formik>

完整代码下载

完整代码下载

http://www.lryc.cn/news/141995.html

相关文章:

  • 开始MySQL之路——外键关联和多表联合查询详细概述
  • 无涯教程-PHP - intval() 函数
  • 2023年国赛数学建模思路 - 案例:粒子群算法
  • 【1++的数据结构】之map与set(一)
  • Ubuntu断电重启后黑屏左上角光标闪烁,分辨率低解决办法,ubuntu系统display只有4:3 怎么办?太卡
  • Java 微服务当中POST form 、url、json的区别
  • repo 常用命令汇总——202308
  • [Linux]命令行参数和进程优先级
  • Android13新特性之通知权限提升
  • 206. 反转链表 (简单系列)
  • 攻防世界-Fakebook
  • 0基础入门C++之类和对象下篇
  • ECMAScript 2023
  • 爬虫实战之使用 Python 的 Scrapy 库开发网络爬虫详解
  • 【面试题】UDP和TCP有啥区别?
  • 字节实习后端面试总结(C++/GO)
  • linux 自动登录SSH
  • 量化:pandas基础
  • 华为云渲染实践
  • SpringBoot注解详解:从核心到Web,从数据到测试,一网打尽
  • Java寻找奇数
  • WinPlan经营大脑:精准预测,科学决策,助力企业赢得未来
  • 多数据源切换以及事务处理
  • docker 重装提示 Exising installation is up to date 解决方法
  • k8s分散部署节点之pod反亲和性(podAntiAffinity)
  • 大A的造血与吸血能力
  • 【数据库】使用ShardingSphere+Mybatis-Plus实现读写分离
  • 【第三方接口】阿里云内容审核SDK的使用
  • IDEA软件安装包分享(附安装教程)
  • 尚硅谷宋红康MySQL笔记 10-13