详解对于React结合Antd的Form组件实现登录功能
一、React 结合 Antd 实现登录功能
引入所需的 Antd 组件,代码如下所示:
import { Form, Icon, Input, Button, message } from 'antd'
在 Login.jsx 中,创建一个 Login 组件。当对外暴露组件时,需要使用 Form 组件进行包装,包装 Form 组件生成一个新的组件 Form(Login),同时新组件会向 Form 组件传递一个强大的对象属性 form,这样就可以取到 Form 表单的值,这也是高阶组件和高阶函数的体现,代码如下所示:
class Login extends Component {} const WrapLogin = Form.create()(Login) export default WrapLogin
在 render 内部去渲染表单时,可以先通过 this.props 去拿到 form 表单,在 form 中取得 getFieldDecorator,用于和表单进行双向绑定。在 getFieldDecorator 中,第一项是表单项对应的 value 值,第二项是配置对象,属性名是特定的一些名称。比如,rules 是验证规则,在 rules 中,可以设置 required 为是否必选,message 为校验文案,pattern 为正则表达式校验,max 为最大长度,min 为最小长度。还比如 initialValue 是表单项的初始值。对于 rules 校验,可以使用声明式验证, 也就是直接使用别人定义好的验证规则进行验证,还可以自定义验证 validator,function(rule, value, callback),必须有 callback 回调函数,代码如下所示:
class Login extends Component { validPwd = (rule, value, callback) => { if (!value) { callback('密码必须输入') } else if (value.length < 4) { callback('密码长度不能小于4位') } else if (value.length > 12) { callback('密码长度不能大于12位') } else if (!/^[a-zA-Z0-9_]+$/.test(value)) { callback('密码必须是英文、数字或下划线组成') } else { callback() } } render () { const form = this.props.form const { getFieldDecorator } = form return ( <div className="login"> <header className="login-header"> <img src={logo} alt="logo"></img> <h1>React 后台管理系统</h1> </header> <section className="login-content"> <h2>用户登录</h2> <Form> <Form.Item> { getFieldDecorator('username', { rules: [ { required: true, whitespace: true, message: '用户名必须输入'}, { min: 4, message: '用户名至少是4位'}, { max: 12, message: '用户名至少是12位'}, { pattern: /^[a-zA-Z0-9_]+$/, message: '用户名必须是英文、数字或下划线组成'} ], // initialValue: 'admin', })( <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="用户名" /> ) } </Form.Item> <Form.Item> { getFieldDecorator('password', { rules: [ { validator: this.validPwd } ] })( <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="密码" /> ) } </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" className="login-form-button"> 登陆 </Button> </Form.Item> </Form> </section> </div> ) } } const WrapLogin = Form.create()(Login) export default WrapLogin
我们可以定义两个工具类,用来操作登录对象,memoryUtils 是用来在内存保存一些数据的工具模块,storageUtils 是进行 local 数据存储管理的工具模块,如下所示:
memoryUtils.js,代码如下所示:
export default { user: {}, product: {} }
storageUtils.js,代码如下所示:
import store from 'store' const USER_KEY = 'user_key' export default { // 保存 user saveUser (user) { store.set(USER_KEY, user) }, // 读取 user getUser () { return store.get(USER_KEY) || {} }, // 删除 user removeUser () { store.remove(USER_KEY) } }
定义登录的接口请求函数,使用 axios 可以先进行封装,得到 response.data,如下所示:
ajax.js,代码如下所示:
import axios from 'axios' import {message} from 'antd' export default function ajax(url, data={}, type='GET') { return new Promise((resolve, reject) => { let promise if(type==='GET') { promise = axios.get(url, { params: data }) } else { promise = axios.post(url, data) } promise.then(response => { resolve(response.data) }).catch(error => { message.error('请求出错了: ' + error.message) }) }) }
index.js,代码如下所示:
import jsonp from 'jsonp' import ajax from './ajax' import { message } from 'antd' const BASE = '' export const reqLogin = (username, password) => ajax(BASE + '/login', { username, password}, 'POST') export const reqCategories = (parentId) => ajax(BASE + '/manage/category/list', {parentId}) export const reqAddCategories = ({parentId, categoryName}) => ajax(BASE + '/manage/category/add', {parentId, categoryName}, 'POST') export const reqUpdateCategories = ({categoryId, categoryName}) => ajax(BASE + '/manage/category/update', {categoryId, categoryName}, 'POST') export const reqCategory = (categoryId) => ajax(BASE + '/manage/category/info', { categoryId }) export const reqProducts = ({pageNum, pageSize}) => ajax(BASE + '/manage/product/list', { pageNum, pageSize}) export const reqUpdateStatus = ({productId, status}) => ajax(BASE + '/manage/product/updateStatus', {productId, status}, 'POST') export const reqSearchProducts = ({ pageNum, pageSize, searchName, searchType}) => ajax(BASE + '/manage/product/search', { pageNum, pageSize, [searchType]: searchName }) export const reqDeleteImg = (name) => ajax(BASE + '/manage/img/delete', {name}, 'POST') export const reqAddUpdateProduct = (product) => ajax(BASE + '/manage/product/' + (product._id ? 'update' : 'add'), product, 'POST') export const reqRoles = () => ajax(BASE + '/manage/role/list') export const reqAddRole = (roleName) => ajax(BASE + '/manage/role/add', {roleName}, 'POST') export const reqUpdateRole = (role) => ajax(BASE + '/manage/role/update', role, 'POST') export const reqUsers = () => ajax(BASE + '/manage/user/list') export const reqDeleteUser = (userId) => ajax(BASE + '/manage/user/delete', {userId}, 'POST') export const reqAddOrUpdateUser = (user) => ajax(BASE + '/manage/user/'+(user._id ? 'update': 'add'), user, 'POST') export const reqWeather = (city) => { return new Promise((resolve, reject) => { const url = `http://api.map.baidu.com/telematics/v3/weather?location=${city}&output=json&ak=IOXimfoqOUVq2KcYCiQU9cMF7hyN5kFB` jsonp(url, {}, (err, data) => { console.log('jsonp()', err, data) if (!err && data.status==='success') { const {dayPictureUrl, weather} = data.results[0].weather_data[0] resolve({dayPictureUrl, weather}) } else { message.error('获取天气信息失败!') } }) }) }
引入这些工具类和接口,代码如下所示:
import { reqLogin } from '../../api' import memoryUtils from '../../utils/memoryUtils' import storageUtils from '../../utils/storageUtils'
给 Form 表单绑定 onSubmit 事件,handleSubmit。在这个事件中,需要先使用 event.preventDefault() 阻止事件的默认行为。如果想要获取表单项的输入数据,可以使用 form.getFieldsValue()。但是,在提交表单前需要对表单数据进行预校验,使用 this.props.form.validateFields 进行预校验,validateFields 可以获取所有表单字段的值,并且可以判断表单数据是否有错。如有 没错,说明预校验通过,从 values 中获取 username 和 password 的值,然后通过 reqLogin 这个接口结合 async 和 await 发起登录请求。如果响应的状态码正确,说明登录成功,保存 user,保存在内存和本地中,然后使用 this.props.history.replace 跳转到主管理界面中,反之则登录失败。在 render 中,如果用户已经登陆, 需要使用 Redirect 自动跳转到主管理界面中,代码如下所示:
handleSubmit = (event) => { event.preventDefault() this.props.form.validateFields(async (err, values) => { if (!err) { const { username, password } = values const result = await reqLogin(username, password) if (result.status === 0) { message.success('登录成功') const user = result.data memoryUtils.user = user storageUtils.saveUser(user) this.props.history.replace('/') } else { message.error(result.msg) } } else { console.log(err) } })
二、React 结合 Antd 实现登录功能的实现
React 结合 Antd 实现登录功能的实现,完整代码如下所示:
login.jsx,代码如下所示:
import React, { Component } from 'react'import { Form, Icon, Input, Button, message } from 'antd'import { Redirect } from 'react-router-dom' import './login.less' import logo from '../../assets/images/logo.png'import { reqLogin } from '../../api' import memoryUtils from '../../utils/memoryUtils' import storageUtils from '../../utils/storageUtils' class Login extends Component { handleSubmit = (event) => { event.preventDefault() this.props.form.validateFields(async (err, values) => { if (!err) { const { username, password } = values const result = await reqLogin(username, password) if (result.status === 0) { message.success('登录成功') const user = result.data memoryUtils.user = user storageUtils.saveUser(user) this.props.history.replace('/') } else { message.error(result.msg) } } else { console.log(err) } }) } validPwd = (rule, value, callback) => { if (!value) { callback('密码必须输入') } else if (value.length < 4) { callback('密码长度不能小于4位') } else if (value.length > 12) { callback('密码长度不能大于12位') } else if (!/^[a-zA-Z0-9_]+$/.test(value)) { callback('密码必须是英文、数字或下划线组成') } else { callback() } } render () { const user = memoryUtils.user if (user && user._id) { return <Redirect to="/"></Redirect> } const form = this.props.form const { getFieldDecorator } = form return ( <div className="login"> <header className="login-header"> <img src={logo} alt="logo"></img> <h1>React 后台管理系统</h1> </header> <section className="login-content"> <h2>用户登录</h2> <Form onSubmit={this.handleSubmit}> <Form.Item> { getFieldDecorator('username', { rules: [ { required: true, whitespace: true, message: '用户名必须输入'}, { min: 4, message: '用户名至少是4位'}, { max: 12, message: '用户名至少是12位'}, { pattern: /^[a-zA-Z0-9_]+$/, message: '用户名必须是英文、数字或下划线组成'} ], // initialValue: 'admin', })( <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="用户名" /> ) } </Form.Item> <Form.Item> { getFieldDecorator('password', { rules: [ { validator: this.validPwd } ] })( <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="密码" /> ) } </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" className="login-form-button"> 登陆 </Button> </Form.Item> </Form> </section> </div> ) } } const WrapLogin = Form.create()(Login) export default WrapLogin
login.less,代码如下所示:
.login { width: 100%; height: 100%; background-image: url('./images/bg.jpg'); background-size: 100% 100%; .login-header { display: flex; align-items: center; height: 80px; background-color: rgba(21, 20, 13, 0.5); img { width: 40px; height: 40px; margin: 0 15px 0 50px; } h1 { font-size: 30px; color: white; } } .login-content { width: 400px; height: 300px; background-color: #fff; margin: 50px auto; padding: 20px 40px; h2 { text-align: center; font-size: 30px; font-weight:bold; margin-bottom: 20px; } .login-form { .login-form-button { width: 100%; } } } }
到此这篇关于详解对于React结合Antd的Form组件实现登录功能的文章就介绍到这了,更多相关React Antd Form登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:- Extjs4---Form登录功能的实现,结合struts2
- sping mvc 结合 hibernate 实现用户登录功能(三)!
- Android 使用ViewPager结合PhotoView开源组件实现网络图片在线浏览功能
- 对于Zenity的初步认识,结合shell脚本实现小小功能,通俗易懂!
- node.js学习笔记(3)-node.js结合mysql数据库实现的web项目中常见功能--登录验证、session传值、拦截器、ajax传值等
- 使用React+ndoe.js+mogodb实现注册登录功能
- react的Steps antd组件实现页面局部跳转
- Android 使用ViewPager结合PhotoView开源组件实现网络图片在线浏览功能
- js 处理form表单整理成数组,结合php 完成排序功能的实现
- SpringMVC详解(四)------SSM三大框架整合之登录功能实现
- ant design Form 组件总结 结合Modal 自定义Modal的实现 (Upload Input Select DatePicker Cascader)
- react-native 完整实现登录功能
- 使用JSON技术结合MVC模式C标签实现登录功能
- js 处理form表单整理成数组,结合php 完成排序功能的实现
- react使用antd定制个性化form组件
- react antd form组件的使用
- 详解React中传入组件的props改变时更新组件的几种实现方法
- 结合开源软件kaptcha讲解登录验证码功能的实现
- vue实现短信验证码登录功能(流程详解)
- redis+php实现微博(一)注册与登录功能详解