文章目录

  • 概要
  • 前端讲解
  • 登录组件
  • 注册组件
  • 用户列表组件
  • 后端讲解
  • 连接数据库db.js
  • 路由routes.js
  • express应用app.js
  • 启动项目
  • 小结


概要

上一篇博客🚪中,我们已经成功实现了登录注册系统的基本功能。现在,我们将进一步完善系统,实现查看用户列表的功能,并通过Ant Design组件库对界面进行优化。并讲解上一篇博客里详细的代码解释

antdesign表单校验图片上传_react.js

前端讲解

登录组件

利用antd组件库提供的forminputbuttonmessage等UI组件组成登录的前端界面,输入邮箱和密码登录,前端用onFinish函数根据<Form.Item>里的name属性得到前端输入框中得到的数据,将这些数据通过axios发送给后端服务器中,再处理对应的逻辑,再对后端返回的数据做处理,然后导入react-router-dom里面的useNavigate属性进行跳转界面,实例化一个函数,再用navigate跳转到用户列表界面

import React from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { Form, Input, Button,message } from 'antd';
// import { LockOutlined } from '@ant-design/icons';
import axios from 'axios';


const Login = () => {
  // const [email, setEmail] = useState('');
  // const [password, setPassword] = useState('');
  const navigate = useNavigate();

  const onFinish = (n) => {
    console.log(n.email);
    console.log(n.password);
    axios({
      method: 'post',
      url: 'http://localhost:2531/login',
      data: {
        email: n.email,
        password: n.password
      }
    }).then((res) => {
      if (res.data.success) {
        message.success('登陆成功');
        // console.log(`Object ${res.data}`);
        console.log(res.data);
        navigate('/users')
      } else {
        message.success('用户名或密码不正确');
        console.log(res.data);
      }
    }).catch(() => {
      console.log("Something went wrong. Plase try again later");
    });
  };

  return (
    <div className="login1">
    <Form
      name="normal_login"
      labelCol={{
        span: 8,
      }}
      wrapperCol={{
        span: 16,
      }}
      style={{
        maxWidth: 600,
      }}
      className="login-form"
      initialValues={{ remember: true }}
      onFinish={onFinish}
    >

      {/* 邮箱 */}
      <Form.Item
        name="email"
        label="邮箱"
        rules={[{ required: true, message: '请输入邮箱!' }]}
      >
        <Input placeholder="邮箱" 
                // value={email}
                // onChange={(e) => setEmail(e.target.value)}
        />
      </Form.Item>

      {/* 密码 */}
      <Form.Item
        name="password"
        label="密码"
        rules={[{ required: true, message: '请输入密码!' }]}
      >
        <Input.Password
          placeholder="密码"
          // value={password} 
          // onChange={(e) => setPassword(e.target.value)}
        />
      </Form.Item>

      {/* 登录按钮 */}
      <Form.Item
       wrapperCol={{
        offset: 8,
        span: 16,
       }}
      >
        <Button type="primary" htmlType="submit" className="login-form-button">
          登录
        </Button>
        <span className="zhuce">
            <Link to="/register">没有账号?去注册吧!</Link>
        </span>
      </Form.Item>
      
    </Form>
    </div>
  );
};

export default Login;

注册组件

利用antd组件库提供的formCheckboxinputbuttonmessage等UI组件组成注册的前端界面,输入邮箱、密码和验证密码注册,除了确认密码和同意框,其它和登录组件的代码都是类似的,前端用onFinish函数根据<Form.Item>里的name属性得到前端输入框中得到的数据,将这些数据通过axios发送给后端服务器中,再处理对应的逻辑,再对后端返回的数据做处理,然后用navigate跳转到登录界面,下面我就讲解确认密码和同意框的使用:

dependencies={['password']}依赖password字段,即确认密码的验证规则依赖于密码字段,比较两次输入的密码是否相等

<Form.Item
          name="confirm1"
          label="验证密码"
          dependencies={['password']}
          hasFeedback
          rules={[
            {
              required: true,
              message: '请再一次填入密码!',
            },
            ({ getFieldValue }) => ({
              validator(_, value) {
                if (!value || getFieldValue('password') === value) {
                  return Promise.resolve();
                }
                return Promise.reject(new Error('两次密码不符!'));
              },
            }),
          ]}
        >
          <Input.Password 
          placeholder="重新输入密码"
          />
      </Form.Item>

接受协议通过验证value的值如果 value 的值为真(即用户勾选了协议),则返回一个 resolved 状态的 Promise,表示验证通过。如果 value 的值为假(即用户未勾选协议),则返回一个 rejected 状态的 Promise,其中包含了一个错误对象,错误消息为 Should accept agreement,表示用户应该接受协议。

<Form.Item
          name="agreement"
          valuePropName="checked"
          rules={[
            {
              validator: (_, value) =>
                value ? Promise.resolve() : Promise.reject(new Error('Should accept agreement')),
            },
          ]}
          {...tailFormItemLayout}
        >
          <Checkbox>
            I have read the <span>agreement</span>
          </Checkbox>
      </Form.Item>

antdesign表单校验图片上传_ios_02


antdesign表单校验图片上传_数据_03


antdesign表单校验图片上传_node.js_04

用户列表组件

导入React库中的useStateuseEffect钩子,以及axios库,用于发送HTTP请求,使用useState钩子来声明了一个名为users的状态变量,并初始化为一个空数组,setUsers 是用来更新 users 状态的函数,使用 useEffect 钩子来执行副作用操作,即发送 HTTP 请求获取用户数据。在组件挂载时(空依赖数组 []),执行传入的回调函数。在回调函数中,定义了一个名为 fetchData 的异步函数,用于发送 GET 请求到指定的 URL 获取用户数据。获取数据后,通过 setUsers 更新 users 状态为获取到的用户数据,返回部分包含了从状态变量 users 中映射出的用户数据

优化界面:使用Ant Design的组件库,我们可以很容易地优化用户列表页面的界面,使其更加美观和易用。在UserList组件中,我们将使用 Ant Design 的 Table 组件来展示用户数据。

首先定义用户表单字段对应表中什么字段值,例如用户id对应users表里的id,邮箱对应users表里的email等等

antdesign表单校验图片上传_ios_05


再把原先的ul列表改为Table组件,设置columns属性值和dataSource数据,其中数据是来自之前useState里面的users状态变量

antdesign表单校验图片上传_ios_06

后端讲解

连接数据库db.js

用mysql2连接数据库,使用nodejs数据库里的users(id,email,password)表进行操作

antdesign表单校验图片上传_antdesign表单校验图片上传_07

路由routes.js

routes.js里根据路由管理不同的请求,根据前端axios获取的数据发送到后端req.body,通过结构赋值得到传入的邮箱和密码信息,再调用控制器写好的函数,然后返回给前端信息是否成功和message信息

antdesign表单校验图片上传_node.js_08

express应用app.js

在app.js里,创建一个Express应用实例app,导入cors和bodyParser中间件,用来处理跨域请求和解析URL编码格式和JSON格式的HTTP请求体,再导入routes.js,挂载路由到根路径上,最后启动应用并监听2531端口

antdesign表单校验图片上传_antdesign表单校验图片上传_09

启动项目

启动前端npm start,启动后端node server/app.js,就可以访问到根路径的一个界面

antdesign表单校验图片上传_ios_10


点击登录,输入数据库里已经注册了的邮箱和密码,显示登录成功

antdesign表单校验图片上传_node.js_11


点击注册,输入数据库里没有的邮箱和密码,显示注册成功,数据库里就多出一条数据

antdesign表单校验图片上传_antdesign表单校验图片上传_12


点击用户列表,可以查看到数据库里user表的所有数据以列表的形式展示

antdesign表单校验图片上传_react.js_13

小结

通过本篇博客,我们进一步完善了基于React和Express的登录注册系统,实现了用户列表的展示功能,并通过Ant Design组件库对界面进行了优化。这样的改进不仅提升了系统的可用性和用户体验,也为今后的功能扩展和项目开发奠定了基础。

在下一步,我们可以考虑进一步扩展系统的功能,例如添加用户信息的编辑和删除功能,以及加强系统的安全性和稳定性。
希望本文能够帮助读者更好地了解React的使用,如果有任何疑问或者建议,欢迎留言讨论🌹