react开发前端登录、注册、找回密码页面的详细教程

2023-05-16

登录、注册、找回密码是前端项目经常遇到的需求。

光标自动定位到输入框、回车登录、图形验证码、邮箱验证码、60秒倒计时、字段校验、字段提示语、上传头像、密码显示隐藏这些功能都会在本文中详细介绍,【注意】使用的ui库是antd

目录

光标自动定位到输入框

回车登录

图形验证码

邮箱验证码

60秒倒计时

邮箱字段校验和字段提示语

上传头像

密码显示隐藏

截图

项目源代码


光标自动定位到输入框

使用autoFocus属性

          <Input
            addonBefore="邮箱/账号"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            placeholder="邮箱/账号"
            className="m-login-input"
            autoFocus
          />

回车登录

          <Input
            addonBefore="验证码"
            value={code}
            maxLength={6}
            onChange={(e) => setCode(e.target.value)}
            onKeyUp={(e) => handleEnter(e)}
            placeholder="验证码"
            className="m-login-input"
          />
  const handleEnter = (e) => {
    if (e.keyCode === 13) {
      handleLogin()
    }
  }

图形验证码

        <div className="m-login-row">
          <Input
            addonBefore="验证码"
            value={code}
            maxLength={6}
            onChange={(e) => setCode(e.target.value)}
            onKeyUp={(e) => handleEnter(e)}
            placeholder="验证码"
            className="m-login-input"
          />
        </div>
        <div className="m-login-row">
          <div
            className="m-ai-login-code"
            onClick={getCaptcha}
            dangerouslySetInnerHTML={{ __html: captcha }}
          ></div>
        </div>
  const getCaptcha = () => {
    Api.h5.userCaptcha({}).then((res) => {
      if (res.code === 200) {
        const { captchaId, captcha } = res.data
        setCaptcha(captcha)
        setCaptchaId(captchaId)
      }
    })
  }

邮箱验证码

            <Form.Item
              label=""
              name="username"
              rules={[
                {
                  required: true,
                  message: '请输入邮箱!',
                },
                {
                  validator: (e, value) => checkEmail(e, value),
                },
              ]}
            >
              <Input
                addonBefore="邮箱"
                addonAfter={
                  <Popover
                    placement="left"
                    title={'提示'}
                    content={'某些用户的邮件会发送到垃圾箱'}
                    trigger="click"
                  >
                    <Icon
                      name="help"
                      className="m-ai-register-addon-after"
                    ></Icon>
                  </Popover>
                }
                onPressEnter={(e) => e.preventDefault()}
              />
            </Form.Item>

60秒倒计时

            <Form.Item
              label=""
              name="emailCode"
              rules={[
                {
                  required: true,
                  message: '请输入邮箱验证码!',
                },
                {
                  len: 6,
                  message: '邮箱验证码为6位',
                },
              ]}
            >
              <Input
                addonBefore="邮箱验证码"
                addonAfter={
                  <div>
                    <Button
                      type="link"
                      size="small"
                      disabled={isSendEmail}
                      className="m-ai-register-send-email-btn"
                      onClick={handleSendEmail}
                    >
                      {isSendEmail ? (
                        <span>{count}秒后重新发送</span>
                      ) : (
                        <span>发送</span>
                      )}
                    </Button>
                  </div>
                }
                onPressEnter={(e) => e.preventDefault()}
              />
            </Form.Item>
  const handleSendEmail = () => {
    const username = form.getFieldValue('username')
    if (regExp.test(username)) {
      Api.h5.userSendEmailCode({ username }).then((res) => {
        if (res.code === 200) {
          setEmailId(res.data.emailId)
          message.success(res.message)
          setCount(process.env.REACT_APP_MODE === 'dev' ? 6 : 180)
          setIsSendEmail(true)
        }
      })
    } else {
      message.info('请输入正确的邮箱')
    }
  }  

useEffect(() => {
    clearTimeout(timer)
    timer = setTimeout(() => {
      if (count > 1) {
        setCount(count - 1)
      } else {
        setIsSendEmail(false)
      }
    }, 1000)
    // eslint-disable-next-line
  }, [count])

邮箱字段校验和字段提示语

            <Form.Item
              label=""
              name="username"
              rules={[
                {
                  required: true,
                  message: '请输入邮箱!',
                },
                {
                  validator: (e, value) => checkEmail(e, value),
                },
              ]}
            >
              <Input
                addonBefore="邮箱"
                addonAfter={
                  <Popover
                    placement="left"
                    title={'提示'}
                    content={'某些用户的邮件会发送到垃圾箱'}
                    trigger="click"
                  >
                    <Icon
                      name="help"
                      className="m-ai-register-addon-after"
                    ></Icon>
                  </Popover>
                }
                onPressEnter={(e) => e.preventDefault()}
              />
            </Form.Item>
  let regExp = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/
  const checkEmail = (e, value) => {
    //let regExp = /\w+[@][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)/
    if (regExp.test(value)) {
      return Promise.resolve()
    } else {
      return Promise.reject(new Error('请输入正确的邮箱'))
    }
  }

上传头像

            <Form.Item label="头像" name="avatar">
              <UploadImgToCNDMobile
                type={'edit'}
                imgDir={`img/userAvatar`}
                filePrefix={'m=register'}
                uploadType={2}
              ></UploadImgToCNDMobile>
            </Form.Item>
import React, { useState } from 'react'
import { ImageUploader, Dialog } from 'antd-mobile'
import { v4 as uuidv4 } from 'uuid'
import {
  imageUrlFormat,
  uploadImgGetTokenFromLocalStorage,
  uploadGetTokenFromLocalStorageForH5,
} from '../../utils/tools'
import urls from '../../api/urls'
import axios from 'axios'

export default function UploadImgToCND({
  value = '',
  msg,
  type = 'add',
  onChange,
  accept = '.jpg,.png,.jpeg',
  imgUrlCnd,
  imgDir = 'img',
  filePrefix = '',
  uploadType = 1,
}) {
  const imageUrl = imageUrlFormat(imgUrlCnd)
  let defaultValue = {
    uid: '-1',
    name: imageUrl,
    status: 'done',
    url: imageUrl,
  }
  const [fileList, setFileList] = useState(value ? [defaultValue] : [])

  const mockUpload = async (file) => {
    const uid = uuidv4()
    const reslutIndex = Array.from(file.name).findLastIndex(
      (item) => item === '.'
    )
    const fileName = uid + file.name.slice(reslutIndex, file.name.length)
    let token
    if (uploadType === 1) {
      token = uploadImgGetTokenFromLocalStorage()
    } else if (uploadType === 2) {
      token = uploadGetTokenFromLocalStorageForH5()
    } else {
      token = uploadImgGetTokenFromLocalStorage()
    }
    const data = new FormData()
    data.append('file', file)
    data.append(
      'key',
      `${imgDir}/${filePrefix ? filePrefix + '-' : ''}${fileName}`
    )
    data.append('fname', fileName)
    data.append('token', token)
    await axios({
      url: urls.light.uploadToCDN,
      method: 'post',
      data,
    }).then((res) => {
      if (res.data.code === 200) {
        typeof onChange === 'function' && onChange(res.data.data.key)
      }
    })

    return {
      url: URL.createObjectURL(file),
    }
  }

  return (
    <span>
      {type !== 'check' ? (
        <ImageUploader
          value={fileList}
          onChange={(info) => {
            if (Array.isArray(info) && info.length === 0) {
              typeof onChange === 'function' && onChange(undefined)
            }
            console.log(info)
            setFileList(info)
          }}
          upload={mockUpload}
          maxCount={1}
          onDelete={() => {
            return Dialog.confirm({
              content: '是否确认删除',
            })
          }}
        />
      ) : value ? (
        <img src={imageUrl} alt={imageUrl} className="m-upload-img-check"></img>
      ) : null}
    </span>
  )
}

密码显示隐藏

          <Input.Password
            addonBefore="密码"
            value={password}
            type="password"
            onChange={(e) => setPassword(e.target.value)}
            onKeyUp={(e) => handleEnter(e)}
            placeholder="密码"
            className="m-login-input"
          />

截图

 

项目源代码

https://github.com/xutongbao/learn-chatgpt

有问题可以评论区讨论

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

react开发前端登录、注册、找回密码页面的详细教程 的相关文章

  • ubuntu20.04配置TensorFlow-GPU版本+对应版本的cuda&cudnn

    ubuntu20 04配置TensorFlow GPU版本 43 对应版本的cuda amp cudnn 配置说明 操作系统是Ubuntu20 04 xff0c GPU是NVIDIA GeForce RTX 2080 Ti xff0c Py
  • 十四、Rust ORM 框架

    Rust 下的 orm xff0c 之前笔者介绍过 sqlx xff0c 但使用中发现 sqlx 在进行参数绑定时 xff0c 使用的是 宏 xff0c 在当前的 IDE 生态环境下 xff0c 有时不能很好的进行代码提示 xff0c 或代
  • mybatis源码之集成mybatis-plus源码

    本文将结合源码介绍mybatis plus的原理 xff0c 包括 xff1a BaseMapper APIMybatisSqlSessionFactoryBean类BaseMapper API Statement解析Wrapper查询构建
  • Jpa 插入更新如何过滤null值

    使用Jpa时 xff0c 默认的save方法会将entity中null的值也更新到数据库 xff0c 这对与存在默认值或者更新接口将直接导致错误的记录产生 xff0c 那么如何解决这个问题 xff1f Hibernate提供了两个注解 64
  • 一个奇怪的java.lang.IncompatibleClassChangeError异常

    解决方法就是替换jdk版本 xff0c 下面都是废话 最近项目进行了一次小更新 xff0c 添加了一个很小很小的功能 xff0c 结果运行一段时间后莫名出现java lang IncompatibleClassChangeError xff
  • nginx的proxy_pass最后反斜杠/的问题

    如果只是host xff0c 如http host 带 xff1a 用代理的内容替换掉匹配的路径 不带 xff1a 拼接上匹配的路径 2 xff1a 如果是子路径 xff0c 如http host func 带和不带 xff1a 用代理的内
  • gitlab修改克隆地址

    1 修改gitlab yml文件 xff0c 修改gitlab下的host和port vi opt gitlab embedded service gitlab rails config gitlab yml 修改完成后执行gitlab c
  • 结构体成员——数组或指针

    结构体成员是C类型的字符数组 表示字符串时 c语言中没有字符串类型 xff0c 只能使用字符数组表示字符串 当定义结构体时 xff0c 成员是字符数组时 xff0c 在外部给该成员赋值 xff0c 不能使用 结构体把变量名 成员名 61 3
  • C++遍历输出enum枚举类型

    enum DAY MON TUE WED THU FRI SAT SUN 问题 如果使用如下方式来遍历 xff0c 则编译器会报类型转换失败错误 xff0c 因为enum类型没有 43 43 运算符 xff0c 也不支持 43 运算 for
  • Kali Linux

    为什么我输入git clone 43 网址显示无法访问啊
  • Android自定义标题栏异常You cannot combine custom titles with other title features

    我们在使用自定义标题栏时 xff0c 一般的写法基本上是下面几步 requestWindowFeature Window FEATURE CUSTOM TITLE setContentView R layout activity test
  • Kotlin中使用Dagger2 可能导致错误"Dagger does not support injection into private fields"

    Kotlin 生成 java文件时属性默认为 private xff0c 给属性添加 64 JvmField 声明可以转成 public class User var name String 61 null val age Int 61 2
  • [linux]ubuntu22安装mysql5.7.40

    导语 xff1a ubuntu22 04 强制安装mysql5 7 40 安装完安装其他apt依赖的时候 可能会造成mysql出问题 最好还是离线环境用 apt update apt get install zip y cd var rm
  • winxp 远程rdp 连接 Ubuntu10.10-再次远程登陆失败 (二)

    在文章winxp 远程rdp 连接 Ubuntu10 10 一 操作完成 xff0c 并且进行第一成功登陆之后 xff0c 退出 xff08 注销 直接关闭mstsc退出按钮 xff09 远程连接之后 xff0c 重新登录出现 xff0c
  • PostGIS教程七:几何图形(Geometry)

    目录 一 介绍 二 元数据表 三 表示真实世界的对象 3 1 点 xff08 Points xff09 3 2 线串 xff08 Linestring xff09 3 3 多边形 xff08 Polygon xff09 3 4 集合 xff
  • FreeBSD下修改安装源的方法

    FreeBSD默认是从官方的源下载软件包的 xff0c 速度比较慢 xff0c 可以修改配置文件指定国内的镜像源来快速安装软件 说明 xff1a FreeBSD中安装软件一般有两种方式 xff1a xff08 一 xff09 使用pk ad
  • sqlite3_bind

    sqlite3 bind text 中绑定的指针 xff0c 在sqlite3 step 时必须存在 xff0c 不能释放 xff0c 否则会是乱码 sqlite3 bind blob中绑定的指针 xff0c 在sqlite3 step 时
  • Windows10 Clion 无法打开文件cudart.lib

    真是巨坑 xff0c 遇到这个问题 xff0c 且耗费两个小时百度 google xff0c 差点放弃换用Visual Studio xff0c 但真实原因竟然这么简单 在你的CmakeList txt中 xff0c 是不是这样添加cuda
  • cf规则介绍

    codeforces的正确打开方式 1 背景 可能很多人都久闻codeforces网站的大名 xff0c 却苦于各种各样的区域性问题或玄学问题 xff0c 没能真正地体验到cf所带来的极致魅力 而网络上关于这方面的博文太少了 xff08 至
  • 使用Buildroot + QEMU构建和运行Linux

    使用Buildroot 43 QEMU构建和运行Linux xunknown 64 2022 04 06 概述 Buildroot是一个用于为嵌入式系统构建完整的Linux系统 xff08 包括Bootloader xff0c Linux

随机推荐

  • openwrt 无线中继设置–固定IP+打印服务器和文件共享

    openwrt 无线中继设置 固定IP 43 打印服务器和文件共享 因为给TPLINK703N xff0c 编译16MROM成功 xff0c 固件里加入了打印服务器和SAMBA VSFTPD USB挂载等功能 xff0c 可使用有线连接上级
  • Linux 终端(TTY)

    原文 xff1a Linux 终端 TTY sparkdev 博客园 Linux 终端 TTY TTY 是 Teletype 或 Teletypewriter 的缩写 xff0c 原来是指电传打字机 xff0c 后来这种设备逐渐键盘和显示器
  • shell命令和变量//区分变量未定义和变量已定义但值为空

    转载 xff1a Shell Command Language 参考 xff1a shell How to check if a variable is set in Bash Stack Overflow 关键 xff1a 形如 para
  • 区分本地终端和ssh远程终端

    如果本地和远端服务器用户名和主机名 xff0c 终端颜色配置都一致 xff0c 通过ssh登陆服务器的时候 xff0c 在本地终端和ssh终端来回切换时 xff0c 傻傻分不清当前终端是本地终端还是ssh远程服务器 下面这个连接介绍了一种方
  • 电路仿真软件Circuit JS1修改菜单字体大小

    在线演示 xff1a https www falstad com circuit circuitjs html 下载地址 xff1a https www falstad com circuit offline circuitjs1 linu
  • Ubuntu 22.04配置samba服务器

    安装samba sudo apt install samba 可以验证一下安装结果 xff1a smbd version 创建samba用户密码 创建samba用户 xff08 可选 xff09 xff1a sudo adduser sys
  • 一个查找文件的类:它的长处在于能够搜索子目录并且是可控制的

    find file cpp Defines the entry point for the console application include 34 stdafx h 34 测试需要的头文件 include lt conio h gt
  • Clearwater IMS All-in-one环境搭建指导书

    xunknown 64 163 com 2015 01 13 一 前言 Clearwater IMS 是一个开源的 IMS 项目 提供 VoIP SIP 电话等功能 Clearwater IMS 主页 http www projectcle
  • Clearwater IMS All-in-one环境搭建指导书

    xunknown 64 163 com 2015 01 13 一 前言 Clearwater IMS 是一个开源的 IMS 项目 提供 VoIP SIP 电话等功能 Clearwater IMS 主页 http www projectcle
  • Sublime Text3注册码(亲测可用 2019-11-19)

    转自博客中的朋友的 xff0c 用于保存 适用于Sublime Text2同时也适用于Sublime Text3 1 打开本地hosts文件 Windows路径是C Windows System32 drivers etc MacOS路径是
  • H3C配置多区域OSPF实验

    一 先上拓扑 xff1a 二 实验环境 xff1a Windows 10 xff08 21H1 xff09 xff0c HCL版本 xff1a V3 0 1 xff08 华三模拟器 xff09 三 实验需求 xff1a SWA SWB SW
  • 配置mysql使用ssl连接,配置java连接mysql使用ssl

    查看mysql是否支持ssl连接 show variables like 39 ssl 39 生成服务器端 openssl genrsa 2048 gt ca key pem openssl req sha1 new x509 nodes
  • Python中的命名规范

    变量命名准则 您应当尽量使自己的变量命名含义清晰 xff0c 不要使用混乱的字母 数字 表情等意义不明的字符来命名变量一般来说 xff0c 您不应当使自己的风格频发变换 如果可能 xff0c 请将整个项目保持统一风格此文章根据本人习惯与编码
  • Linux下达梦数据库的安装与卸载

    文章目录 Linux下达梦数据库的安装与卸载1 安装前准备工作1 1 下载安装包1 2 检查Linux Unix 系统信息1 3 创建安装用户1 4 Linux Unix 下检查操作系统限制1 5 设置JAVA环境 2 安装DM2 1 解压
  • 递归算法实现角谷定理

    问题重述 xff1a 角谷定理 输入一个自然数 xff0c 若为偶数 xff0c 则把它除以 2 xff0c 若为奇数 xff0c 则把它乘以 3 加 1 经过如此有限次运算后 xff0c 总可以得到自然数值 1 求经过多少次可得到自然数
  • windows系统关闭node进程

    taskkill f t im node exe Node js是一个开源的 跨平台的JavaScript运行时环境 xff0c 它允许开发者在服务器端使用JavaScript进行编程 Node js的诞生极大地扩展了JavaScript的
  • 我的GPT-4 API 接入之旅

    3月15日open ai推出GPT 4 https platform openai com docs models gpt 4 chatgpt免费体验入口 xff1a http chat xutongbao top 需要排队 28号加入等候
  • IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

    git exe pull progress v no rebase 34 origin 34 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 6
  • 制作高清chatgpt logo

    lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt meta http equiv 61 34 X U
  • react开发前端登录、注册、找回密码页面的详细教程

    登录 注册 找回密码是前端项目经常遇到的需求 光标自动定位到输入框 回车登录 图形验证码 邮箱验证码 60秒倒计时 字段校验 字段提示语 上传头像 密码显示隐藏这些功能都会在本文中详细介绍 xff0c 注意 使用的ui库是antd 目录 光