react + zarm + react-captcha-code + classnames 实现登录注册页面

Posted 凯小默:树上的男爵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react + zarm + react-captcha-code + classnames 实现登录注册页面相关的知识,希望对你有一定的参考价值。

需要实现的效果

代码实现过程

上一篇我们搭建了开发环境的基本结构:Vite 2.x + React + Zarm + Less + React Router v6 + Axios + flexible.js 搭建前端 H5 开发环境,下面我们开始实现登记注册页面的开发。

1.准备字体库

首先我们在https://www.iconfont.cn/新建一个项目

然后再项目里面添加字体图标,可以自己搜索想要的图标添加入库


然后把入库的图标添加到项目里



最后在我们项目那里生成在线链接即可

2.创建图标公用组件

我们新建 components/CustomIcon/index.jsx,添加如下代码:

// 自定义 Iconfont 图标,提供了一个 createFromIconfont 方法,方便开发者调用在 iconfont.cn 上自行管理的图标。
import  Icon  from 'zarm';
// 这里直接使用我们上面弄的项目字体链接
export default Icon.createFromIconfont('//at.alicdn.com/t/font_3376813_il53dc6ij5.js');

3.安装验证码插件

https://www.npmjs.com/package/react-captcha-code

基于 React 和 canvas 的一个验证码组件.

npm i react-captcha-code -S
import React,  useCallback, useRef  from 'react';
import Captcha from 'react-captcha-code';

export const Basic = () => 
  const handleChange = useCallback((captcha) => 
    console.log('captcha:', captcha);
  , []);

  const captchaRef = useRef<htmlCanvasElement>();

  const handleClick = () => 
    // 刷新验证码
    (captchaRef as any).current.refresh();
  ;

  return (
    <>
      <Captcha ref=captchaRef charNum=6 onChange=handleChange />
      <div>
        <button onClick=handleClick>更换验证码</button>
      </div>
    </>
  );
;

4.安装类名连接classnames

https://www.npmjs.com/package/classnames

一个简单的 javascript 实用程序,用于有条件地将类名连接在一起。

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo',  bar: true ); // => 'foo bar'
classNames( 'foo-bar': true ); // => 'foo-bar'
classNames( 'foo-bar': false ); // => ''
classNames( foo: true ,  bar: true ); // => 'foo bar'
classNames( foo: true, bar: true ); // => 'foo bar'

// lots of arguments of various types
classNames('foo',  bar: true, duck: false , 'baz',  quux: true ); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1,  baz: null , ''); // => 'bar 1'

5.组件编写

我们新建 src/container/Login 文件夹,用于存放登录注册模块相关代码

交互逻辑:写在 index.jsx 里面

import  useState, useCallback  from 'react'
import  Cell, Input, Button, Toast  from 'zarm'
import CustomIcon from '@/components/CustomIcon'
import Captcha from "react-captcha-code"
import classNames from "classNames"
import  login, register  from "./api/index"

import s from './style.module.less'

const Login = () => 
  const [username, setUsername] = useState(''); // 账号
  const [password, setPassword] = useState(''); // 密码
  const [verify, setVerify] = useState(''); // 验证码
  const [captcha, setCaptcha] = useState(''); // 验证码变化后存储值
  const [type, setType] = useState('login'); // 登录注册类型

  // 验证码变化,回调方法
  const handleChange = useCallback((captcha) => 
    console.log('验证码变化,回调方法', captcha)
    setCaptcha(captcha)
  , []);

  const onSubmit = async () => 
    if (!username) 
      Toast.show('请输入账号')
      return
    
    if (!password) 
      Toast.show('请输入密码')
      return
    
    try 
      // 判断是否是登录状态
      if (type == 'login') 
        // 执行登录接口,获取 token
        const  status, desc, data  = await login(
          username,
          password
        );
        console.log('登录接口', status, data)
        if(status === 200) 
          // 将 token 写入 localStorage
          localStorage.setItem('token', data.token);
          Toast.show('登录成功');
         else 
          Toast.show(desc);
        
       else 
        if (!verify) 
          Toast.show('请输入验证码')
          return
        ;
        if (verify != captcha) 
          Toast.show('验证码错误')
          return
        ;
        const  status, desc, data  = await register(
          username,
          password
        );
        console.log('注册接口', status, data)
        if(status === 200) 
          Toast.show('注册成功');
          // 注册成功,自动将 tab 切换到 login 状态
          setType('login');
         else 
          Toast.show(desc);
        
      
     catch (error) 
      Toast.show('系统错误');
    
  ;

  return <div className=s.auth>
    <div className=s.head />
    <div className=s.tab>
      <span className=classNames( [s.avtive]: type == 'login' ) onClick=() => setType('login')>登录</span>
      <span className=classNames( [s.avtive]: type == 'register' ) onClick=() => setType('register')>注册</span>
    </div>
    <div className=s.form>
      <Cell icon=<CustomIcon type="user" />>
        <Input
          clearable
          type="text"
          placeholder="请输入账号"
          onChange=(value) => setUsername(value)
        />
      </Cell>
      <Cell icon=<CustomIcon type="password" />>
        <Input
          clearable
          type="password"
          placeholder="请输入密码"
          onChange=(value) => setPassword(value)
        />
      </Cell>
      
        type == 'register' ? <Cell icon=<CustomIcon type="captcha" />>
          <Input
            clearable
            type="text"
            placeholder="请输入验证码"
            onChange=(value) => setVerify(value)
          />
          <Captcha charNum=4 onChange=handleChange />
        </Cell> : null
      
    </div>
    <div className=s.operation>
      <Button block theme="primary" onClick=onSubmit>type == 'login' ? '登录' : '注册'</Button>
    </div>
  </div>


export default Login

样式:写在 style.module.less 里,图片我这边放在了 src/assets/images 里面

.auth 
    min-height: 100vh;
    background-image: linear-gradient(217deg, #6fb9f8, #3daaf85e, #49d3fc1a, #3fd3ff00);
    .head 
      height: 200px;
        background: url('@/assets/images/cryptocurrency.png') no-repeat center;
        background-size: 120%;
        border-bottom-left-radius: 12px;
        border-bottom-right-radius: 12px;
        img 
          width: 34px;
          margin: 15px 0 0 15px;
        
    
    .tab 
      color: #597fe7;
      padding: 30px 24px 10px 24px;
      > span 
        margin-right: 10px;
        font-size: 14px;
        font-weight: bold;
        &.avtive 
          font-size: 20px;
          border-bottom: 2PX solid #597fe7;
          padding-bottom: 6px;
        
      
    
    .form 
      padding: 0 6px;
      :global 
        .za-cell 
          background-color: transparent;
          &::after 
            border-top: none;
          
        
      
    
    .operation 
      padding: 10px 24px 0 24px;
    
  

接口配置:写在 api/index.js

import  fetchData  from "@/utils/axios.js";

// 注册
export function register(data) 
  return fetchData('/api/user/register', 'post', data);

// 登录
export function login(data) 
  return fetchData('/api/user/login', 'post', data);

6.测试

先注册已经注册过的账号试试:kaimo313,123456

注册正常的账号:注册成功之后就会切换到登录的模块


我们看到本地数据库里已经注册成功了。

然后我们登录账号 kaimo313,123456

登录成功之后,token 会被存起来,然后跳转到我们的首页

以上是关于react + zarm + react-captcha-code + classnames 实现登录注册页面的主要内容,如果未能解决你的问题,请参考以下文章

react + zarm 实现账单列表类型以及时间条件弹窗封装

react + zarm 实现底部导航栏

react + zarm 实现账单详情页以及编辑删除功能

react + zarm + antV F2 实现账单数据统计饼图效果

Vite 2.x + React + Zarm + Less + React Router v6 + Axios + flexible.js 搭建前端 H5 开发环境

react + zarm + rc-form + crypto-js 实现个人中心页面,头像上传,密码重置,登录退出功能