您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關怎么在React中利用Form組件實現一個登錄功能,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
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> <h2>React 后臺管理系統</h2> </header> <section className="login-content"> <h3>用戶登錄</h3> <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 實現登錄功能的實現,完整代碼如下所示:
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> <h2>React 后臺管理系統</h2> </header> <section className="login-content"> <h3>用戶登錄</h3> <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; } h2 { font-size: 30px; color: white; } } .login-content { width: 400px; height: 300px; background-color: #fff; margin: 50px auto; padding: 20px 40px; h3 { text-align: center; font-size: 30px; font-weight:bold; margin-bottom: 20px; } .login-form { .login-form-button { width: 100%; } } } }
以上就是怎么在React中利用Form組件實現一個登錄功能,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。