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;
}

猜你喜欢

转载自blog.csdn.net/m0_46612221/article/details/128500340