ReactNative 密码生成器实战

news2024/11/19 7:47:55

效果展示图

在这里插入图片描述

使用插件

  • 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>
            <TextInput
              style={styles.inputStyle}
              placeholder="Ex. 8"
              keyboardType="numeric"
            />
          </View>
          <View style={styles.inputWrapper}>
            <Text style={styles.heading}>是否包含小写字母</Text>
            <BouncyCheckbox
              disableBuiltInState
              isChecked={lowerCase}
              fillColor="#29AB87"
            />
          </View>
          <View style={styles.inputWrapper}>
            <Text style={styles.heading}>是否包括大写字母</Text>
            <BouncyCheckbox
              disableBuiltInState
              isChecked={upperCase}
              fillColor="#FED85D"
            />
          </View>
          <View style={styles.inputWrapper}>
            <Text style={styles.heading}>是否包括数字</Text>
            <BouncyCheckbox
              disableBuiltInState
              isChecked={numbers}
              onPress={() => setNumbers(!numbers)}
              fillColor="#C9A0DC"
            />
          </View>
          <View style={styles.inputWrapper}>
            <Text style={styles.heading}>是否包含符号</Text>
            <BouncyCheckbox
              disableBuiltInState
              isChecked={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 属性

具体的代码如下:

<Formik
  initialValues={{ 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>
        <TextInput
          style={styles.inputStyle}
          value={values.passwordLength}
          onChangeText={handleChange("passwordLength")}
          placeholder="例如:8"
          keyboardType="numeric"
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.heading}>是否包含小写字母</Text>
        <BouncyCheckbox
          disableBuiltInState
          isChecked={lowerCase}
          onPress={() => setLowerCase(!lowerCase)}
          fillColor="#29AB87"
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.heading}>是否包括大写字母</Text>
        <BouncyCheckbox
          disableBuiltInState
          isChecked={upperCase}
          onPress={() => setUpperCase(!upperCase)}
          fillColor="#FED85D"
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.heading}>是否包括数字</Text>
        <BouncyCheckbox
          disableBuiltInState
          isChecked={numbers}
          onPress={() => setNumbers(!numbers)}
          fillColor="#C9A0DC"
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.heading}>是否包含符号</Text>
        <BouncyCheckbox
          disableBuiltInState
          isChecked={symbols}
          onPress={() => setSymbols(!symbols)}
          fillColor="#FC80A5"
        />
      </View>
      <View style={styles.formActions}>
        <TouchableOpacity
          disabled={!isValid}
          style={styles.primaryBtn}
          onPress={() => handleSubmit()}
        >
          <Text style={styles.primaryBtnTxt}>生成密码</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.secondaryBtn}
          onPress={() => {
            handleReset();
            resetPasswordState();
          }}
        >
          <Text style={styles.secondaryBtnTxt}>重置</Text>
        </TouchableOpacity>
      </View>
    </>
  )}
</Formik>

完整代码下载

完整代码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/919751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【第三阶段】kotlin语言内置函数with

1.with基本上和run一样&#xff0c;只是使用方式不一致 info.run、with(info) 2.with函数返回类型是根据匿名函数最后一行的类型变化而变化 with 函数里面持有的是this 3.具名操作 package Stage3fun main() {val info"kotlin"//具名操作//thisinfo 等价info传入…

言有三新书出版,《深度学习之图像识别(全彩版)》上市发行,配套超详细的原理讲解与丰富的实战案例!...

各位同学&#xff0c;今天有三来发布新书了&#xff0c;名为《深度学习之图像识别&#xff1a;核心算法与实战案例&#xff08;全彩版&#xff09;》&#xff0c;本次书籍为我写作并出版的第6本书籍。 前言 2019年5月份我写作了《深度学习之图像识别&#xff1a;核心技术与案例…

2023-8-23 堆排序

题目链接&#xff1a;堆排序 #include <iostream>using namespace std;const int N 100010;int n, m; int h[N], Size;void down(int u) {int t u;if(u * 2 < Size && h[u * 2] < h[t]) t u * 2;if(u * 2 1 < Size && h[u * 2 1] < h…

使用go语言、Python脚本搭建一个简单的chatgpt服务网站。

使用go语言、Python脚本搭建一个简单的GPT服务网站 前言 研0在暑假想提升一下自己&#xff0c;自学了go语言编程和机器学习相关学习&#xff0c;但是一味学习理论&#xff0c;终究是枯燥的&#xff0c;于是自己弄点小项目做。 在这之前&#xff0c;建议您需要掌握以下两个技…

纹波和噪声测试知识

随着开关频率和开关速度不断的提升&#xff0c;在使用开关型的DC/DC电源的时候&#xff0c;要特别关注输入输出电源的纹波。但是测量DC/DC电源的纹波和噪声没有一个行业标准。不同厂家的测试环境以及测试标准都不太一样&#xff0c;导致很多人很迷惑。这篇文章提供了一个简单可…

为什么网络互联地址设置为30位地址

对于点对点链路&#xff0c;为了节约IPv4地址&#xff0c;一般为其分配/30地址块&#xff0c;这样包含4个地址&#xff1a;最小地址作为网络地址&#xff0c;最大地址作为广播地址&#xff0c;剩余两个可分配地址&#xff0c;分配给链路两端的接口&#xff0c;这是最普遍的方法…

stm32之14.超声波测距代码

-------------------- 源码 void sr04_init(void) { GPIO_InitTypeDef GPIO_InitStructure; //打开端口B的硬件时钟&#xff0c;就是供电 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //打开端口E的硬件时钟&#xff0c;就是供电 RC…

Electron学习3 使用serialport操作串口

Electron学习3 使用serialport操作串口 一、准备工作二、 SerialPort 介绍1. 核心软件包(1) serialport(2) serialport/stream(3) serialport/bindings-cpp(4) serialport/binding-mock(5) serialport/bindings-interface 2. 解析器包3. 命令行工具 三、创建一个demo程序1. 创建…

自平衡性:保持数据结构稳定的关键

自平衡性是一种重要的数据结构属性&#xff0c;它确保在执行插入、删除等操作后&#xff0c;数据结构能够自动进行调整&#xff0c;以保持整体的平衡状态。平衡的数据结构可以提供更快的操作性能&#xff0c;避免极端情况下的低效操作&#xff0c;同时保持树或其他结构的整体稳…

【C语言】动态内存管理(malloc,free,calloc,realloc)-- 详解

一、动态内存分配 定义&#xff1a;动态内存分配 (Dynamic Memory Allocation) 就是指在程序执行的过程中&#xff0c;动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样&#xff0c;需要预先分配存储空间&#xff0c;而是由系统根据程…

JVM——类加载与字节码技术—字节码指令

2.字节码指令 2.1 入门 jvm的解释器可以识别平台无关的字节码指令&#xff0c;解释为机器码执行。 2a b7 00 01 b1 this . init&#xff08;&#xff09; return 准备了System.out对象&#xff0c;准备了参数“hello world”,准备了对象的方法println(String)V&#xff…

车载充电器日本PSE认证申请资料和流程

PSE认证是日本针对电气用品的一个强制性安全认证。 日本的采购商在购进商品后一个月内必须向日本经济产业省&#xff08;METI&#xff09;注册申报。在日本市场上销售的DENAN目录范围内的电气电子产品都必须通过PSE认证。日本DENAN将电气电子产品分为两类&#xff1a;特定电气…

CSS background 背景

background属性为元素添加背景效果。 它是以下属性的简写&#xff0c;按顺序为&#xff1a; background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 以下所有示例中的花花.jpg图片的大小是4848。 1 background-color background-col…

【面试专题】Spring篇①

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;Java面试专题 目录 1.你知道 Spring 框架中有哪些重要的模块吗&#xff1f; 2. 谈谈你对 IOC 的认识。 3. 谈谈你对 AOP 的认识。 4.在实际写代码时&#xff0c;有没有用到过 AOP&#xff1f;用…

数字化技术无限延伸,VR全景点亮智慧生活

随着互联网的发展&#xff0c;我们无时无刻不再享受着互联网给我们带来的便利&#xff0c;数字化生活正在无限延伸&#xff0c;各行各业也开始积极布局智能生活。要说智慧生活哪个方面应用的比较多&#xff0c;那应该就是VR全景了&#xff0c;目前VR全景已经被各个行业广泛应用…

PyPI 如何在本地配置访问不同的仓库地址

PyPI 是可以在本地计算机上进行配置来访问远程的仓库地址的。 检查配置文件 检查配置文件使用的命令为&#xff1a; pip config -v list 通过上面的配置文件&#xff0c;我们可以知道 Python 的 PyPI 的配置文件信息。 上面图片显示的是配置文件的扫描路径。 修改 pip.ini…

flink checkpoint时exact-one模式和atleastone模式的区别

背景&#xff1a; flink在开启checkpoint的时候有两种模式可以选择&#xff0c;exact-one和atleastone模式&#xff0c;那么这两种模式有什么区别呢&#xff1f; exact-one和atleastone模式的区别 先说结论&#xff1a;exact-one可以完全做到状态的一致性&#xff0c;而atle…

gorm中正确的使用json数据类型

一、说明 1、JSON 数据类型是 MySQL 5.7.8 开始支持的。在此之前&#xff0c;只能通过字符类型&#xff08;CHAR&#xff0c;VARCHAR 或 TEXT &#xff09;来保存 JSON 文档。现实中也很多人不会采用json的存储方式&#xff0c;直接定义一个字符类型,让前端转换传递进来,返回给…

Spring Boot多环境指定yml或者properties

Spring Boot多环境指定yml或者properties 文章目录 Spring Boot多环境指定yml或者properties加载顺序配置指定某个yml 加载顺序 ● application-local.properties ● application.properties ● application-local.yml ● application.yml application.propertes server.port…

2023前端面试笔记 —— CSS3

系列文章目录 内容链接2023前端面试笔记HTML52023前端面试笔记CSS3 文章目录 系列文章目录前言一、CSS选择器的优先级二、通过 CSS 的哪些方式可以实现隐藏页面上的元素三、px、em、rem之间有什么区别&#xff1f;四、让元素水平居中的方法有哪些五、在 CSS 中有哪些定位方式六…