纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

React Antd Form登录 详解对于React结合Antd的Form组件实现登录功能

浮生离梦   2021-04-06 我要评论
想了解详解对于React结合Antd的Form组件实现登录功能的相关内容吗浮生离梦在本文为您仔细讲解React Antd Form登录的相关知识和一些Code实例欢迎阅读和指正我们先划重点:React,Antd,Form登录,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 校验可以使用声明式验证 也就是直接使用别人定义好的验证规则进行验证还可以自定义验证 validatorfunction(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%;
   }
  }
 }
}



相关文章

猜您喜欢

网友评论

Copyright 2020 www.Videogametimes.com 【视游时光】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式