最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

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

在 render 內(nèi)部去渲染表單時,可以先通過 this.props 去拿到 form 表單,在 form 中取得 getFieldDecorator,用于和表單進(jìn)行雙向綁定。在 getFieldDecorator 中,第一項是表單項對應(yīng)的 value 值,第二項是配置對象,屬性名是特定的一些名稱。比如,rules 是驗證規(guī)則,在 rules 中,可以設(shè)置 required 為是否必選,message 為校驗文案,pattern 為正則表達(dá)式校驗,max 為最大長度,min 為最小長度。還比如 initialValue 是表單項的初始值。對于 rules 校驗,可以使用聲明式驗證, 也就是直接使用別人定義好的驗證規(guī)則進(jì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('密碼長度不能小于4位')
  } else if (value.length > 12) {
   callback('密碼長度不能大于12位')
  } else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
   callback('密碼必須是英文、數(shù)字或下劃線組成')
  } 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ǒng)</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: '用戶名必須是英文、數(shù)字或下劃線組成'}
         ],
         // 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 是用來在內(nèi)存保存一些數(shù)據(jù)的工具模塊,storageUtils 是進(jìn)行 local 數(shù)據(jù)存儲管理的工具模塊,如下所示:

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

定義登錄的接口請求函數(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('請求出錯了: ' + 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() 阻止事件的默認(rèn)行為。如果想要獲取表單項的輸入數(shù)據(jù),可以使用 form.getFieldsValue()。但是,在提交表單前需要對表單數(shù)據(jù)進(jìn)行預(yù)校驗,使用 this.props.form.validateFields 進(jìn)行預(yù)校驗,validateFields 可以獲取所有表單字段的值,并且可以判斷表單數(shù)據(jù)是否有錯。如有 沒錯,說明預(yù)校驗通過,從 values 中獲取 username 和 password 的值,然后通過 reqLogin 這個接口結(jié)合 async 和 await 發(fā)起登錄請求。如果響應(yīng)的狀態(tài)碼正確,說明登錄成功,保存 user,保存在內(nèi)存和本地中,然后使用 this.props.history.replace 跳轉(zhuǎn)到主管理界面中,反之則登錄失敗。在 render 中,如果用戶已經(jīng)登陸, 需要使用 Redirect 自動跳轉(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 實現(xiàn)登錄功能的實現(xiàn)

React 結(jié)合 Antd 實現(xiàn)登錄功能的實現(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('密碼長度不能小于4位')
  } else if (value.length > 12) {
   callback('密碼長度不能大于12位')
  } else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
   callback('密碼必須是英文、數(shù)字或下劃線組成')
  } 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ǒng)</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: '用戶名必須是英文、數(shù)字或下劃線組成'}
         ],
         // 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%;
   }
  }
 }
}


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

相關(guān)文章

  • React中useState的使用方法及注意事項

    React中useState的使用方法及注意事項

    useState通過在函數(shù)組件里調(diào)用它來給組件添加一些內(nèi)部state,下面這篇文章主要給大家介紹了關(guān)于React中useState的使用方法及注意事項的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • vite+react+tailwindcss的簡單使用方式

    vite+react+tailwindcss的簡單使用方式

    這篇文章主要介紹了vite+react+tailwindcss的簡單使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • React?函數(shù)式組件和類式組件詳情

    React?函數(shù)式組件和類式組件詳情

    這篇文章主要介紹了React函數(shù)式組件和類式組件詳情,React是組件化的的JS庫,組件化也是React的核心思想,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • 詳解react-webpack2-熱模塊替換[HMR]

    詳解react-webpack2-熱模塊替換[HMR]

    這篇文章主要介紹了詳解react-webpack2-熱模塊替換[HMR], 小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 淺談React Event實現(xiàn)原理

    淺談React Event實現(xiàn)原理

    這篇文章主要介紹了淺談React Event實現(xiàn)原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • react?app?rewrited替代品craco使用示例

    react?app?rewrited替代品craco使用示例

    這篇文章主要為大家介紹了react?app?rewrited替代品craco使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • React中useState原理的代碼簡單實現(xiàn)

    React中useState原理的代碼簡單實現(xiàn)

    要實現(xiàn)useState的背后原理,則需要深入了解狀態(tài)是如何在函數(shù)組件的渲染周期中保持和更新的,本文將通過一段代碼簡單闡述useState鉤子函數(shù)的實現(xiàn)思路,希望對大家有所幫助
    2023-12-12
  • React組件實例三大屬性state props refs使用詳解

    React組件實例三大屬性state props refs使用詳解

    這篇文章主要為大家介紹了React組件實例三大屬性state props refs使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • react echarts刷新不顯示問題的解決方法

    react echarts刷新不顯示問題的解決方法

    最近在寫項目的時候遇到了一個問題,當(dāng)編輯完代碼后echarts圖正常展示 , 可再次刷新頁面 , echarts會消失,所以本文給大家介紹了react echarts刷新不顯示問題原因和解決方法,需要的朋友可以參考下
    2024-02-02
  • 淺談react前后端同構(gòu)渲染

    淺談react前后端同構(gòu)渲染

    本篇文章主要介紹了淺談react前后端同構(gòu)渲染,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論

神农架林区| 建昌县| 蛟河市| 白城市| 林芝县| 商水县| 中江县| 绥阳县| 温宿县| 壤塘县| 柞水县| 石首市| 巴南区| 宿州市| 突泉县| 乐东| 玉门市| 政和县| 宝清县| 鄯善县| 乌鲁木齐市| 广灵县| 喀什市| 镇江市| 米脂县| 桐庐县| 渑池县| 黄大仙区| 汝南县| 英吉沙县| 鄢陵县| 鸡西市| 黄平县| 尚义县| 砀山县| 迁西县| 磴口县| 保康县| 彭阳县| 平谷区| 若尔盖县|