Ant Design助力:实现用户列表的优雅展示与管理

文章目录

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

概要

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

前端讲解

登录组件

利用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>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用户列表组件

导入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等等
在这里插入图片描述
再把原先的ul列表改为Table组件,设置columns属性值和dataSource数据,其中数据是来自之前useState里面的users状态变量
在这里插入图片描述

后端讲解

连接数据库db.js

用mysql2连接数据库,使用nodejs数据库里的users(id,email,password)表进行操作
在这里插入图片描述

路由routes.js

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

express应用app.js

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

启动项目

启动前端npm start,启动后端node server/app.js,就可以访问到根路径的一个界面
在这里插入图片描述
点击登录,输入数据库里已经注册了的邮箱和密码,显示登录成功
在这里插入图片描述
点击注册,输入数据库里没有的邮箱和密码,显示注册成功,数据库里就多出一条数据
在这里插入图片描述
点击用户列表,可以查看到数据库里user表的所有数据以列表的形式展示
在这里插入图片描述

小结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/589027.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

File contains parsing errors: file:///etc/yum.repos.d/nginx.repo报错解决,文件配置出现问题

执行yum指令出现以下错误&#xff1a; 解决方案&#xff1a;yum的配置文件出现问题&#xff0c; 先删除yum.repos.d目录下所有文件 rm -f /etc/yum.repos.d/* 然后重新下载阿里的资源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.…

您想拥有一个属于你自己的GPT-3.5-turbo吗?来吧,开始行动起来吧!!!

背景: 在2024年4月的时候,openai公司宣布GPT-3.5-turbo免费使用,无需注册!!! 多么激动人心的消息啊!!! 但是,如何你想申请一个openai api key的时候,发现调用失败,直接报Rate Limit!!! 无语了!!! 不过没关系,我们另辟捷径!!! 下面就开始我的表演啦…

python可视化学习笔记折线图问题-起始点问题

问题描述&#xff1a; 起始点的位置不对 from pyecharts.charts import Line import pyecharts.options as opts # 示例数据 x_data [1,2,3,4,5] y_data [1, 2, 3, 4, 5] # 创建 Line 图表 line Line() line.add_xaxis(x_data) line.add_yaxis("test", y_data) li…

【全网最全】2024五一数学建模B题论文+前四问代码多种保奖进阶思路+建模过程+代码+数据处理+论文写作技巧等(后续会更新)

一定要点击文末的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接加入群聊【2024五一数学建模】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&khoTDlhAS5N_Ffp-vucfG5WjeeJFxsWbz&authKey7oCSHS25VqSLauZ2PpiewRQ9D9PklaCxVS5X6i%2BAkDrey992f0t15…

【hackmyvm】vivifytech靶机

渗透思路 信息收集端口扫描端口服务信息目录扫描爆破hydra--sshgit提权 信息收集 ┌──(kali㉿kali)-[~] └─$ fping -ag 192.168.9.0/24 2>/dev/null 192.168.9.119 --主机 192.168.9.164 --靶机个人习惯&#xff0c;也方便后续操作&#xff0c;将IP地址赋值给一个变…

两院院士泌尿外科专家吴阶平教授

吴阶平&#xff08;1917-2011&#xff09;&#xff0c;男&#xff0c;江苏常州人&#xff0c;1933年天津汇文中学毕业&#xff0c;保送到北平燕京大学医预科&#xff0c;1937年毕业于北平燕京大学获理学士学位&#xff0c;1942年毕业于北平协和医学院获医学博士学位&#xff0c…

使用 Langchain、Langfuse、Nemo-gaurdrails、RAGAs构建 RAG 管道并进行监控和评估

原文地址:build-end-to-end-rag-pipeline-with-monitoring-and-evaluation-using-langchain-azure-ai-search 2024 年 4 月 21 日 介绍 使用现代的LLM框架,如Langchain或llamaindex,可以迅速搭建一个用于 RAG 的管道,通常只需编写大约5-6行代码。然而,若要构建一个适用于生…

短视频素材去哪里搬运?短视频素材有哪些类型?

在这个数字化和视觉传达至关重要的时代&#xff0c;选择合适的视频素材对于提升视频内容的吸引力和观众参与度至关重要。无论您是一名广告制片人、社交媒体经理还是独立视频制作者&#xff0c;以下这些精选的视频素材网站将为您提供从高清视频到特效资源的全面支持&#xff0c;…

HSDB使用教程

HSDB&#xff1a;Hostspot Debugger&#xff0c;JVM内置的工具&#xff0c;用于深入分析JVM运行时的内部状态 启动HSDB java -cp D:/tools/jdk-1.8/lib/sa-jdi.jar sun.jvm.hotspot.HSDB 获取进程id jps 连接到指定进程 查找类 通过查询查找对象 输入查询语句 select d from …

算法复杂度分析:揭秘隐藏的计算之谜

复杂度 算法的复杂度指的是执行该算法的程序在运行时所需要的时间和空间资源。时间复杂度不是代码真正的时间&#xff0c;而是数据规模的增长所表达的趋势。 算法的复杂度分析分为时间复杂度和空间复杂度。一般我们说的多的是算法的时间复杂度&#xff0c;希望通过较少时间执行…

iOS 实现视图遮罩效果

有时候&#xff0c;我们会遇到这种需求&#xff0c;只讲视图的某个部分展示出来 这时候&#xff0c;我们可以通过设置该视图layer.mask layerb来实现&#xff0c;需要注意的是&#xff0c;这里的layerb必须要设置backgroundColor&#xff0c;渐变layer有colors,否则达不到效果…

ubuntu sudo apt-get install neo4j 配置安装与设置远程访问

文章目录 下载Adding the Debian repositoryInstalling Neo4j安装流程设置远程访问 下载 neo4j 官方的下载地址&#xff0c;进入页面之后&#xff0c;往下滑&#xff1a; https://neo4j.com/deployment-center/#community 点击 Visit https://debian.neo4j.com/ Adding the …

链表(数组实现的伟大二踢脚)

一.链表与数组 链表作为 C 语言中一种基础的数据结构&#xff0c;在平时写程序的时候用的并不多&#xff0c;但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛&#xff0c;所以必须要搞懂链表&#xff0c;链表分为单向链表和双向链表&#xff0c;单向链表很少…

2024.5.1【项目测试报告】模拟微信实现网页聊天室

目录 项目介绍 核心功能 额外拓展 核心技术 项目页面设计 注册页面 登录页面 找回密码页面 网页聊天室页面 个人中心页面 测试计划 功能测试 注册页面 登录页面 找回密码页面 个人中心页面 网页聊天室页面 自动化测试 单例驱动 获取屏幕截图 注册页面自动化测…

GPG的使用

这里写自定义目录标题 安装加密程序生成加密密钥怎么备份自己的密钥就可以使用公钥加密邮件信息了 安装加密程序 下载gpg4win&#xff1a; https://www.gpg4win.org/index.html 免费的&#xff0c;如果使用的是苹果电脑&#xff0c;使用https://gpgtools.org/。 如果是linux&a…

【精选文献】JAG|基于时序Sentinel-1 SAR影像小农耕作区烟草空间分布制图

目录 文章简介 01 文章摘要 02 研究背景、目标及创新点 03 研究区域与数据集 04 研究方法 05 研究结果 06 研究讨论 07 研究结论 08 文章引用 文章简介 论文名称&#xff1a;Mapping tobacco planting areas in smallholder farmlands using Phenological-Spatial-Te…

golang判断通道chan是否关闭的2种方式

chan通道在go语言的办法编程中使用频繁&#xff0c;我们可以通过以下2种方式来判断channel通道是否已经关闭&#xff0c;1是使用 for range循环&#xff0c;另外是通过 for循环中if 简短语句的 逗号 ok 模式来判断。 示例代码如下&#xff1a; //方式1 通过for range形式判断…

LNMP部署wordpress

1.环境准备 总体架构介绍 序号类型名称外网地址内网地址软件02负载均衡服务器lb0110.0.0.5192.168.88.5nginx keepalived03负载均衡服务器lb0210.0.0.6192.168.88.6nginx keepalived04web服务器web0110.0.0.7192.168.88.7nginx05web服务器web0210.0.0.8192.168.88.8nginx06we…

Nodejs -- 流程控制库

流程控制库 尾触发和next 尾触发最多的应用是在Connect的中间件 var app connect() app.use(connect.staticCache()) app.use(connect.static(__dirname /public)) app.use(conect.cokkieParser()) app.use(connect.session()) app.use(connect.query()) app.use(connect.…

跨平台终端软件——quardCRT

作为一个技术栈比较复杂的程序&#xff0c;工作常常会在windows/linux/macos等不同的平台切换开发&#xff0c;开发过程中最常用的就是终端工具了&#xff0c;一个趁手的终端可以成倍的提高工作效率&#xff0c;因此我一直希望能找个一个跨平台体验一致无缝切换的终端软件&…
最新文章