欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解對(duì)于React結(jié)合Antd的Form組件實(shí)現(xiàn)登錄功能

 更新時(shí)間:2021年04月06日 11:33:28   作者:浮生離夢(mèng)  
這篇文章主要介紹了詳解對(duì)于React結(jié)合Antd的Form組件實(shí)現(xiàn)登錄功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、React 結(jié)合 Antd 實(shí)現(xiàn)登錄功能

引入所需的 Antd 組件,代碼如下所示:

import { Form, Icon, Input, Button, message } from 'antd'

在 Login.jsx 中,創(chuàng)建一個(gè) Login 組件。當(dāng)對(duì)外暴露組件時(shí),需要使用 Form 組件進(jìn)行包裝,包裝 Form 組件生成一個(gè)新的組件 Form(Login),同時(shí)新組件會(huì)向 Form 組件傳遞一個(gè)強(qiáng)大的對(duì)象屬性 form,這樣就可以取到 Form 表單的值,這也是高階組件和高階函數(shù)的體現(xiàn),代碼如下所示:

class Login extends Component {}
const WrapLogin = Form.create()(Login)
export default WrapLogin

在 render 內(nèi)部去渲染表單時(shí),可以先通過(guò) this.props 去拿到 form 表單,在 form 中取得 getFieldDecorator,用于和表單進(jìn)行雙向綁定。在 getFieldDecorator 中,第一項(xiàng)是表單項(xiàng)對(duì)應(yīng)的 value 值,第二項(xiàng)是配置對(duì)象,屬性名是特定的一些名稱(chēng)。比如,rules 是驗(yàn)證規(guī)則,在 rules 中,可以設(shè)置 required 為是否必選,message 為校驗(yàn)文案,pattern 為正則表達(dá)式校驗(yàn),max 為最大長(zhǎng)度,min 為最小長(zhǎng)度。還比如 initialValue 是表單項(xiàng)的初始值。對(duì)于 rules 校驗(yàn),可以使用聲明式驗(yàn)證, 也就是直接使用別人定義好的驗(yàn)證規(guī)則進(jìn)行驗(yàn)證,還可以自定義驗(yàn)證 validator,function(rule, value, callback),必須有 callback 回調(diào)函數(shù),代碼如下所示:

class Login extends Component {
 validPwd = (rule, value, callback) => {
  if (!value) {
   callback('密碼必須輸入')
  } else if (value.length < 4) {
   callback('密碼長(zhǎng)度不能小于4位')
  } else if (value.length > 12) {
   callback('密碼長(zhǎng)度不能大于12位')
  } else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
   callback('密碼必須是英文、數(shù)字或下劃線(xiàn)組成')
  } 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 后臺(tái)管理系統(tǒng)</h1>
    </header>
    <section className="login-content">
     <h2>用戶(hù)登錄</h2>
     <Form>
      <Form.Item>
       {
        getFieldDecorator('username', { 
         rules: [
          { required: true, whitespace: true, message: '用戶(hù)名必須輸入'},
          { min: 4, message: '用戶(hù)名至少是4位'},
          { max: 12, message: '用戶(hù)名至少是12位'},
          { pattern: /^[a-zA-Z0-9_]+$/, message: '用戶(hù)名必須是英文、數(shù)字或下劃線(xiàn)組成'}
         ],
         // initialValue: 'admin', 
        })(
         <Input
          prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
          placeholder="用戶(hù)名"
         />
        )
       }
      </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

我們可以定義兩個(gè)工具類(lèi),用來(lái)操作登錄對(duì)象,memoryUtils 是用來(lái)在內(nèi)存保存一些數(shù)據(jù)的工具模塊,storageUtils 是進(jìn)行 local 數(shù)據(jù)存儲(chǔ)管理的工具模塊,如下所示:

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)
 }
}

定義登錄的接口請(qǐng)求函數(shù),使用 axios 可以先進(jìn)行封裝,得到 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('請(qǐng)求出錯(cuò)了: ' + 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('獲取天氣信息失敗!')
   }

  })
 })
}

引入這些工具類(lèi)和接口,代碼如下所示:

import { reqLogin } from '../../api'
import memoryUtils from '../../utils/memoryUtils'
import storageUtils from '../../utils/storageUtils'

給 Form 表單綁定 onSubmit 事件,handleSubmit。在這個(gè)事件中,需要先使用 event.preventDefault() 阻止事件的默認(rèn)行為。如果想要獲取表單項(xiàng)的輸入數(shù)據(jù),可以使用 form.getFieldsValue()。但是,在提交表單前需要對(duì)表單數(shù)據(jù)進(jìn)行預(yù)校驗(yàn),使用 this.props.form.validateFields 進(jìn)行預(yù)校驗(yàn),validateFields 可以獲取所有表單字段的值,并且可以判斷表單數(shù)據(jù)是否有錯(cuò)。如有 沒(méi)錯(cuò),說(shuō)明預(yù)校驗(yàn)通過(guò),從 values 中獲取 username 和 password 的值,然后通過(guò) reqLogin 這個(gè)接口結(jié)合 async 和 await 發(fā)起登錄請(qǐng)求。如果響應(yīng)的狀態(tài)碼正確,說(shuō)明登錄成功,保存 user,保存在內(nèi)存和本地中,然后使用 this.props.history.replace 跳轉(zhuǎn)到主管理界面中,反之則登錄失敗。在 render 中,如果用戶(hù)已經(jīng)登陸, 需要使用 Redirect 自動(dòng)跳轉(zhuǎn)到主管理界面中,代碼如下所示:

 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 結(jié)合 Antd 實(shí)現(xiàn)登錄功能的實(shí)現(xiàn)

React 結(jié)合 Antd 實(shí)現(xiàn)登錄功能的實(shí)現(xiàn),完整代碼如下所示:
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('密碼長(zhǎng)度不能小于4位')
  } else if (value.length > 12) {
   callback('密碼長(zhǎng)度不能大于12位')
  } else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
   callback('密碼必須是英文、數(shù)字或下劃線(xiàn)組成')
  } 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 后臺(tái)管理系統(tǒng)</h1>
    </header>
    <section className="login-content">
     <h2>用戶(hù)登錄</h2>
     <Form onSubmit={this.handleSubmit}>
      <Form.Item>
       {
        getFieldDecorator('username', { 
         rules: [
          { required: true, whitespace: true, message: '用戶(hù)名必須輸入'},
          { min: 4, message: '用戶(hù)名至少是4位'},
          { max: 12, message: '用戶(hù)名至少是12位'},
          { pattern: /^[a-zA-Z0-9_]+$/, message: '用戶(hù)名必須是英文、數(shù)字或下劃線(xiàn)組成'}
         ],
         // initialValue: 'admin',
        })(
         <Input
          prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
          placeholder="用戶(hù)名"
         />
        )
       }
      </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%;
   }
  }
 }
}


到此這篇關(guān)于詳解對(duì)于React結(jié)合Antd的Form組件實(shí)現(xiàn)登錄功能的文章就介紹到這了,更多相關(guān)React Antd Form登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解React setState數(shù)據(jù)更新機(jī)制

    詳解React setState數(shù)據(jù)更新機(jī)制

    這篇文章主要介紹了React setState數(shù)據(jù)更新機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用React框架,感興趣的朋友可以了解下
    2021-04-04
  • 快速創(chuàng)建React項(xiàng)目并配置webpack

    快速創(chuàng)建React項(xiàng)目并配置webpack

    這篇文章主要介紹了創(chuàng)建React項(xiàng)目并配置webpack,在這里需要注意,Create?React?App?requires?Node?14?or?higher.需要安裝高版本的node,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-01-01
  • React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變

    React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變

    這篇文章主要介紹了React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Redux?Toolkit的基本使用示例詳解(Redux工具包)

    Redux?Toolkit的基本使用示例詳解(Redux工具包)

    這篇文章主要介紹了Redux?Toolkit的基本使用,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 使用React?Router?v6?添加身份驗(yàn)證的方法

    使用React?Router?v6?添加身份驗(yàn)證的方法

    這篇文章主要介紹了使用React?Router?v6?進(jìn)行身份驗(yàn)證完全指南,本文將演示如何使用React?Router?v6創(chuàng)建受保護(hù)的路由以及如何添加身份驗(yàn)證,需要的朋友可以參考下
    2022-05-05
  • 詳解React中組件之間通信的方式

    詳解React中組件之間通信的方式

    這篇文章主要介紹了React中組件之間通信的方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • React18?useState何時(shí)執(zhí)行更新及微任務(wù)理解

    React18?useState何時(shí)執(zhí)行更新及微任務(wù)理解

    這篇文章主要為大家介紹了React18?useState何時(shí)執(zhí)行更新及微任務(wù)理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 解決react中useState狀態(tài)異步更新的問(wèn)題

    解決react中useState狀態(tài)異步更新的問(wèn)題

    本文主要介紹了react中useState狀態(tài)異步更新的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • React改變?cè)貥邮降牟僮鞔a

    React改變?cè)貥邮降牟僮鞔a

    這篇文章主要介紹了React技巧之改變?cè)貥邮?本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • Redux DevTools不能顯示數(shù)據(jù)問(wèn)題

    Redux DevTools不能顯示數(shù)據(jù)問(wèn)題

    這篇文章主要介紹了Redux DevTools不能顯示數(shù)據(jù)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論