React实现移动端输入短信验证码页面

Posted 橘猫吃不胖~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React实现移动端输入短信验证码页面相关的知识,希望对你有一定的参考价值。

React实现移动端输入验证码页面

1 效果

大致的功能有:

  • 进入页面自动发送验证码
  • 验证码输入完成后,触发验证码校验
  • 可以手动输入或者删除验证码

效果图如下:

2 输入框实现

验证码输入框部分,主要使用一个input加6个div来展示,在页面上需要将input隐藏掉,6个div显示输入框中的验证码数字,基本实现如下:

import React,  useState, useEffect, useRef  from "react";
import "./index.css";

const CodeInput = (props) => 
  /**
   * vertifyCode:验证码
   * onChange:验证码改变的回调
   * onComplete:验证码输入完成后的回调
   */
  const  vertifyCode = "", onChange, onComplete  = props;

  const [codeArray, setCodeArray] = useState([]); // 用来存放验证码的数组
  const [isFocus, setIsFocus] = useState(false); // 判断是否获取焦点

  const inputList = [...Array(6)].map((item, index) => index); // 生成模拟输入框数组[0,1,2,3,4,5]

  const inputRef = useRef(null); // 绑定input输入框

  // 获取焦点事件
  const handleInputFocus = () => 
    inputRef.current?.focus(); // 为输入框聚焦
    setIsFocus(true);
  ;

  // 获取验证码
  useEffect(() => 
    setCodeArray(vertifyCode.split(""));
  , [vertifyCode]);

  // 当验证码6位时,触发完成事件,校验验证码
  useEffect(() => 
    if (vertifyCode.length !== 6) return; // 验证码不足6位,不触发校验事件
    onComplete && onComplete(vertifyCode);
  , [vertifyCode, onComplete]);

  // 验证码改变事件
  const handleChange = (e) => 
    if (e.target.value) 
      // 获取当前输入的数字
      let val = e.target.value.replace(/[^\\d]/g, ""); // 只保留数字
      onChange?.(val);
     else 
      onChange?.("");
    
  ;

  // 失去焦点
  const handleBlur = () => 
    setIsFocus(false);
  ;

  // 获取焦点
  const handleFocus = () => 
    setIsFocus(true);
  ;

  // 默认聚焦input输入框,每次进入都执行
  useEffect(() => 
    handleInputFocus();
  );

  return (
    <div className="code-input-container" onClick=handleInputFocus>
      /* 验证码数字显示部分 */
      <div className="number-box">
        inputList.map((item, index) => 
          return (
            <div
              className="input-item"
              key=index
              style=
                // 当验证码的长度等于item时,表示当前正在等待下一位的输入,输入框变色
                border: `1px solid $
                  item === codeArray.length && isFocus ? "orange" : "#D9D9D9"
                `,
              
            >
              codeArray[item]
            </div>
          );
        )
      </div>
      /* 输入框,用样式隐藏不显示 */
      <input
        type="number" // 数字类型输入框
        inputMode="numeric" // 可以弹起数字键盘
        maxLength=6 // 最大长度是6
        className="input-value"
        value=vertifyCode // value值为输入的验证码
        ref=inputRef
        onChange=handleChange // 验证码改变事件
        onBlur=handleBlur // 失去焦点事件
        onFocus=handleFocus // 聚焦事件
      />
    </div>
  );
;

export default CodeInput;

基本样式如下:

/* 验证码显示框 */
.number-box 
  display: flex;
  justify-content: space-between;


/* 每一个验证码输入框的样式 */
.input-item 
  margin-right: 15px;
  width: 43px;
  height: 45px;
  display: flex;
  justify-content: center;
  color: #141414;
  font-size: 24px;
  line-height: 45px;
  font-weight: 500;


/* 最后一个验证码输入框margin-right为0 */
.input-item:last-child 
  margin-right: 0px;


/* 将input输入框隐藏看不见 */
.input-value 
  margin-left: -750px;
  position: absolute;
  z-index: -99;
  opacity: 0;

3 整体实现

在整体页面部分中,需要使用useState来存放输入的验证码,并传给验证码输入框,基本代码如下:

import React,  useState, useEffect  from "react";
import CodeInput from "./CodeInput"; // 导入验证码输入框
import "./index.css";

const VertificationCode = () => 
  const [vertifyCode, setVertifyCode] = useState(""); // 保存当前输入的验证码

  // 验证码改变事件
  const handleChange = (vertifyCode) => 
    console.log("当前输入了:", vertifyCode);
    setVertifyCode(vertifyCode); // 更新验证码
  ;

  // 验证码输入完成后进行校验
  const handleComplete = (vertifyCode) => 
    // 验证码输入后验证逻辑
    console.log("验证码输入完毕", vertifyCode);
  ;

  // 请求发送验证码
  const sendVertifyCode = () => 
    // 发送验证码的逻辑
    console.log("验证码已发送");
  ;

  // 重新发送方法
  const handleSend = () => 
    // 重发验证码逻辑,一般情况为:60s倒计时后重新可以再次发送
  ;

  useEffect(() => 
    // 刚进入页面时,发送验证码
    sendVertifyCode();
  , []);

  return (
    <div className="root">
      <div className="title">输入验证码</div>
      <div className="sub-title-container">
        <div className="sub-title">已发送验证码至</div>
        <span className="phone-number">+86 123****0000</span>
      </div>
      <div className="code">
        <CodeInput
          vertifyCode=vertifyCode
          onChange=handleChange
          onComplete=handleComplete
        />
      </div>
      <div className="send-btn" onClick=handleSend>
        重新发送
      </div>
    </div>
  );
;

export default VertificationCode;

基本样式如下:

/* 整体容器样式 */
.root 
  width: 100%;


/* 标题 输入验证码 */
.title 
  font-size: 24px;
  margin: 60px 20px 0;
  color: #141414;
  font-weight: 500;
  line-height: 32px;


/* 描述 已发送验证码至XXX */
.sub-title-container 
  margin: 10px 20px 0;
  font-size: 14px;
  line-height: 17px;


/* 联系方式 */
.phone-number 
  color: #141414;
  letter-spacing: 0;


/* 已发送验证码 */
.sub-title 
  display: inline-block;
  color: #83898f;
  letter-spacing: 0;
  margin-right: 4px;


/* 验证码输入部分 */
.code 
  height: 45px;
  margin: 40px 20px 0;


/* 重新发送 */
.send-btn 
  width: 116px;
  height: 20px;
  color: orange;
  font-weight: 500;
  margin: 20px;
  font-size: 16px;
  line-height: 20px;

以上是关于React实现移动端输入短信验证码页面的主要内容,如果未能解决你的问题,请参考以下文章

vue实现短信验证码登录

关于移动端输入键盘遮挡页面

js实现输入手机验证码后点击提交按钮验证手机输入的验证码和发送的验证码是不是一致

移动端web页面input限制只能输入数字

Spring Security--短信验证码详解

前端angularJS利用directive实现移动端自定义软键盘的方法