ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法を詳しく説明します

ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法を詳しく説明します

1. ReactとAntdを組み合わせてログイン機能を実現

必要な Antd コンポーネントをインポートします。コードは次のとおりです。

'antd' から { フォーム、アイコン、入力、ボタン、メッセージ } をインポートします。

Login.jsx で、Login コンポーネントを作成します。コンポーネントを外部に公開する場合、Form コンポーネントを使用してコンポーネントをラップする必要があります。Form コンポーネントをラップすると、新しいコンポーネント Form (Login) が生成されます。同時に、新しいコンポーネントは強力なオブジェクト プロパティ form を Form コンポーネントに渡し、Form フォームの値を取得できるようにします。これも高階コンポーネントと高階関数の具現化です。コードは次のとおりです。

クラス Login は Component {} を拡張します。
const WrapLogin = Form.create()(ログイン)
デフォルトの WrapLogin をエクスポートする

render 内でフォームをレンダリングする場合、最初に this.props を通じてフォームを取得し、フォームとの双方向バインディングのためにフォーム内で getFieldDecorator を取得できます。 getFieldDecorator では、最初の項目はフォーム項目に対応する値であり、2 番目の項目は構成オブジェクトです。属性名は特定の名前です。たとえば、ルールは検証ルールです。ルールでは、必須かどうかを示す required、検証テキストを示す message、正規表現検証を示す pattern、最大長を示す max、最小長を示す min を設定できます。たとえば、initialValue はフォーム項目の初期値です。ルール検証では、宣言型検証を使用できます。つまり、検証に他の人が定義した検証ルールを直接使用できます。また、検証バリデーター関数 (ルール、値、コールバック) をカスタマイズすることもできます。これには、コールバック関数が必要です。コードは次のとおりです。

クラスLoginはComponentを拡張します{
 validPwd = (ルール、値、コールバック) => {
  if (!値) {
   callback('パスワードを入力する必要があります')
  } それ以外の場合 (値の長さ < 4) {
   callback('パスワードの長さは4文字未満にできません')
  } それ以外の場合 (値の長さ > 12) {
   callback('パスワードの長さは12文字を超えることはできません')
  } そうでない場合 (!/^[a-zA-Z0-9_]+$/.test(値)) {
   callback('パスワードは英語、数字、またはアンダースコアでなければなりません')
  } それ以外 {
   折り返し電話()
  }
 }

 与える () {
  定数フォーム = this.props.form
  const { getFieldDecorator } = フォーム

  戻る (
   <div className="ログイン">
    <header className="ログインヘッダー">
     <img src={logo} alt="ロゴ"></img>
     <h1>React バックエンド管理システム</h1>
    </ヘッダー>
    <セクション className="ログインコンテンツ">
     <h2>ユーザーログイン</h2>
     <フォーム>
      <フォーム.アイテム>
       {
        getFieldDecorator('ユーザー名', { 
         ルール:
          { 必須: true、空白: true、メッセージ: 'ユーザー名は必須です'},
          { 最小: 4、メッセージ: 'ユーザー名は少なくとも 4 文字である必要があります'}、
          { 最大: 12、メッセージ: 'ユーザー名は 12 文字以上である必要があります'},
          { パターン: /^[a-zA-Z0-9_]+$/、メッセージ: 'ユーザー名は英語、数字、またはアンダースコアでなければなりません'}
         ]、
         // 初期値: 'admin', 
        })(
         <入力
          プレフィックス={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}}
          プレースホルダー="ユーザー名"
         />
        )
       }
      </フォーム.アイテム>
      <フォーム.アイテム>
       {
        getFieldDecorator('パスワード', {
         ルール:
          { バリデータ: this.validPwd }
         ]
        })(
         <入力
          プレフィックス={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}}
          タイプ=「パスワード」
          プレースホルダー="パスワード"
         />
        )
       }
      </フォーム.アイテム>
      <フォーム.アイテム>
       <ボタンタイプ="プライマリ" htmlType="送信" className="ログインフォームボタン">
         ログイン</Button>
      </フォーム.アイテム>
     </フォーム>
    </セクション>
   </div>
  )
 }
}

const WrapLogin = Form.create()(ログイン)
デフォルトの WrapLogin をエクスポートする

ログイン オブジェクトを操作するために、2 つのツール クラスを定義できます。MemoryUtils は、メモリにデータを保存するために使用されるツール モジュールであり、storageUtils は、以下に示すように、ローカル データ ストレージ管理用のツール モジュールです。

memoryUtils.js の場合、コードは次のとおりです。

エクスポートデフォルト{
 ユーザー: {},
 製品: {}
}

storageUtils.js のコードは次のとおりです。

'store' からストアをインポートする

定数 USER_KEY = 'user_key'

エクスポートデフォルト{
 // ユーザーを保存
 saveUser (ユーザー) {
  store.set(USER_KEY、ユーザー)
 },

 // ユーザーを読み取り
 取得ユーザー() {
  store.get(USER_KEY) を返します || {}
 },

 // ユーザーを削除
 ユーザーを削除(){
  ストア.削除(USER_KEY)
 }
}

ログイン インターフェイスのリクエスト関数を定義し、最初に axios を使用してそれをカプセル化し、以下に示すように response.data を取得します。

ajax.js の場合、コードは次のようになります。

'axios' から axios をインポートします
'antd' から {message} をインポートします

デフォルト関数 ajax(url, data={}, type='GET') をエクスポートします。

 新しい Promise を返します ((resolve, reject) => {
  約束させる
  if(type==='GET') { 
   プロミス = axios.get(url, {
    パラメータ: データ 
   })
  } それ以外 { 
   プロミス = axios.post(url, データ)
  }
  promise.then(レスポンス => {
   解決(応答データ)
  }).catch(エラー => {
   message.error('リクエストエラー: ' + error.message)
  })
 })

}

index.js の場合、コードは次のようになります。

'jsonp' から jsonp をインポートします
'./ajax' から ajax をインポートします
'antd' から { message } をインポートします

定数BASE = ''

export const reqLogin = (ユーザー名, パスワード) => ajax(BASE + '/login', { ユーザー名, パスワード}, ​​'POST')

エクスポート const reqCategories = (parentId) => ajax(BASE + '/manage/category/list', {parentId})

エクスポート const reqAddCategories = ({parentId, categoryName}) => ajax(BASE + '/manage/category/add', {parentId, categoryName}, 'POST')

エクスポート const reqUpdateCategories = ({categoryId, categoryName}) => ajax(BASE + '/manage/category/update', {categoryId, categoryName}, 'POST')

エクスポート const reqCategory = (categoryId) => ajax(BASE + '/manage/category/info', { categoryId })

エクスポート const reqProducts = ({pageNum, pageSize}) => ajax(BASE + '/manage/product/list', { pageNum, pageSize})

エクスポート const reqUpdateStatus = ({productId, status}) => ajax(BASE + '/manage/product/updateStatus', {productId, status}, 'POST')

エクスポート const reqSearchProducts = ({ pageNum, pageSize, searchName, searchType}) => ajax(BASE + '/manage/product/search', {
 ページ番号、
 ページサイズ、
 [検索タイプ]: 検索名
})

エクスポート const reqDeleteImg = (name) => ajax(BASE + '/manage/img/delete', {name}, 'POST')

エクスポート const reqAddUpdateProduct = (product) => ajax(BASE + '/manage/product/' + (product._id ? 'update' : 'add'), product, 'POST')

エクスポート const reqRoles = () => ajax(BASE + '/manage/role/list')

エクスポート const reqAddRole = (roleName) => ajax(BASE + '/manage/role/add', {roleName}, 'POST')

エクスポート const reqUpdateRole = (role) => ajax(BASE + '/manage/role/update', role, 'POST')

エクスポート const reqUsers = () => ajax(BASE + '/manage/user/list')

エクスポート const reqDeleteUser = (userId) => ajax(BASE + '/manage/user/delete', {userId}, 'POST')

エクスポート const reqAddOrUpdateUser = (user) => ajax(BASE + '/manage/user/'+(user._id ? 'update': 'add'), user, 'POST')

エクスポートconst reqWeather = (都市) => {

 新しい Promise を返します ((resolve, reject) => {
  定数 url = `http://api.map.baidu.com/telematics/v3/weather?location=${city}&output=json&ak=IOXimfoqOUVq2KcYCiQU9cMF7hyN5kFB`
  jsonp(url, {}, (err, データ) => {
   console.log('jsonp()', エラー, データ)
   if (!err && data.status==='success') {
    定数 {dayPictureUrl, weather} = data.results[0].weather_data[0]
    解決({dayPictureUrl, 天気})
   } それ以外 {
    message.error('天気情報を取得できませんでした!')
   }

  })
 })
}

これらのツール クラスとインターフェイスを導入すると、コードは次のようになります。

'../../api' から { reqLogin } をインポートします
'../../utils/memoryUtils' から memoryUtils をインポートします
'../../utils/storageUtils' から storageUtils をインポートします

onSubmit イベントをフォームの handleSubmit にバインドします。このイベントでは、まず event.preventDefault() を使用して、イベントのデフォルトの動作を防止する必要があります。フォーム項目の入力データを取得する場合は、form.getFieldsValue() を使用できます。ただし、フォームを送信する前にフォームデータを事前検証する必要があります。事前検証には this.props.form.validateFields を使用します。validateFields はすべてのフォームフィールドの値を取得し、フォームデータが間違っているかどうかを判断できます。すべてが正しければ、事前検証に合格したことを意味します。values からユーザー名とパスワードの値を取得し、async と await を組み合わせた reqLogin インターフェースを通じてログイン要求を開始します。応答ステータス コードが正しければ、ログインが成功し、ユーザーがメモリとローカルに保存され、this.props.history.replace を使用してメイン管理インターフェイスにジャンプすることを意味します。それ以外の場合、ログインは失敗します。レンダリングでは、ユーザーがすでにログインしている場合は、リダイレクトを使用してメインの管理インターフェースに自動的にジャンプする必要があります。コードは次のとおりです。

 handleSubmit = (イベント) => {
  イベント.preventDefault()

  this.props.form.validateFields(async (err, values) => {
   もしエラーが起きたら
    const { ユーザー名, パスワード } = 値
    const result = await reqLogin(ユーザー名、パスワード)
    結果ステータスが 0 の場合 
     message.success('ログイン成功')
     定数ユーザー = 結果.データ
     メモリユーティリティ.user = ユーザー
     storageUtils.saveUser(ユーザー)
     this.props.history.replace('/')
    } それ以外 { 
     メッセージ.エラー(結果.msg)
    }
   } それ以外 {
    コンソール.log(エラー)
   }
  })

2. ReactとAntdを組み合わせてログイン機能を実現

React は Ant を組み合わせてログイン機能を実装します。完全なコードは次のとおりです。
login.jsx のコードは次のとおりです。

React をインポートします。{ コンポーネント } を 'react' からインポートします。
'antd' から { フォーム、アイコン、入力、ボタン、メッセージ } をインポートします。
'react-router-dom' から { Redirect } をインポートします。
'./login.less' をインポートします
'../../assets/images/logo.png' からロゴをインポートします
'../../api' から { reqLogin } をインポートします
'../../utils/memoryUtils' から memoryUtils をインポートします
'../../utils/storageUtils' から storageUtils をインポートします

クラスLoginはComponentを拡張します{

 handleSubmit = (イベント) => {
  イベント.preventDefault()

  this.props.form.validateFields(async (err, values) => {
   もしエラーが起きたら
    const { ユーザー名, パスワード } = 値
    const result = await reqLogin(ユーザー名、パスワード)
    結果ステータスが 0 の場合 
     message.success('ログイン成功')
     定数ユーザー = 結果.データ
     メモリユーティリティ.user = ユーザー
     storageUtils.saveUser(ユーザー)

     this.props.history.replace('/')
    } それ以外 { 
     メッセージ.エラー(結果.msg)
    }
   } それ以外 {
    コンソール.log(エラー)
   }
  })

 }

 validPwd = (ルール、値、コールバック) => {
  if (!値) {
   callback('パスワードを入力する必要があります')
  } それ以外の場合 (値の長さ < 4) {
   callback('パスワードの長さは4文字未満にできません')
  } それ以外の場合 (値の長さ > 12) {
   callback('パスワードの長さは12文字を超えることはできません')
  } そうでない場合 (!/^[a-zA-Z0-9_]+$/.test(値)) {
   callback('パスワードは英語、数字、またはアンダースコアでなければなりません')
  } それ以外 {
   折り返し電話()
  }
 }


 与える () {

  定数ユーザー = memoryUtils.user
  if (ユーザー && user._id) {
   <Redirect to="/"></Redirect> を返します。
  }

  定数フォーム = this.props.form
  const { getFieldDecorator } = フォーム

  戻る (
   <div className="ログイン">
    <header className="ログインヘッダー">
     <img src={logo} alt="ロゴ"></img>
     <h1>React バックエンド管理システム</h1>
    </ヘッダー>
    <セクション className="ログインコンテンツ">
     <h2>ユーザーログイン</h2>
     <フォーム onSubmit={this.handleSubmit}>
      <フォーム.アイテム>
       {
        getFieldDecorator('ユーザー名', { 
         ルール:
          { 必須: true、空白: true、メッセージ: 'ユーザー名は必須です'},
          { 最小: 4、メッセージ: 'ユーザー名は少なくとも 4 文字である必要があります'}、
          { 最大: 12、メッセージ: 'ユーザー名は 12 文字以上である必要があります'},
          { パターン: /^[a-zA-Z0-9_]+$/、メッセージ: 'ユーザー名は英語、数字、またはアンダースコアでなければなりません'}
         ]、
         // 初期値: 'admin',
        })(
         <入力
          プレフィックス={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}}
          プレースホルダー="ユーザー名"
         />
        )
       }
      </フォーム.アイテム>
      <フォーム.アイテム>
       {
        getFieldDecorator('パスワード', {
         ルール:
          { バリデータ: this.validPwd }
         ]
        })(
         <入力
          プレフィックス={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}}
          タイプ=「パスワード」
          プレースホルダー="パスワード"
         />
        )
       }
      </フォーム.アイテム>
      <フォーム.アイテム>
       <ボタンタイプ="プライマリ" htmlType="送信" className="ログインフォームボタン">
         ログイン</Button>
      </フォーム.アイテム>
     </フォーム>
    </セクション>
   </div>
  )
 }
}

const WrapLogin = Form.create()(ログイン)
デフォルトの WrapLogin をエクスポートする

login.less の場合、コードは次のようになります。

。ログイン {
 幅: 100%;
 高さ: 100%;
 背景画像: url('./images/bg.jpg');
 背景サイズ: 100% 100%;
 .ログインヘッダー{
  ディスプレイ: フレックス;
  アイテムの位置を中央揃えにします。
  高さ: 80px;
  背景色: rgba(21, 20, 13, 0.5);
  画像 {
   幅: 40px;
   高さ: 40px;
   マージン: 0 15px 0 50px;
  }
  h1 {
   フォントサイズ: 30px;
   色: 白;
  }
 }

 .ログインコンテンツ{
  幅: 400ピクセル;
  高さ: 300px;
  背景色: #fff;
  マージン: 50px 自動;
  パディング: 20px 40px;
  h2 {
   テキスト配置: 中央;
   フォントサイズ: 30px;
   フォントの太さ:太字;
   下マージン: 20px;
  }
  .ログインフォーム{
   .ログインフォームボタン{
    幅: 100%;
   }
  }
 }
}


ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法についての記事はこれで終わりです。React Antd Formログインに関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • AntDesign Pro + .NET CoreはJWTベースのログイン認証機能を実装します
  • antd pro に基づく SMS 認証コード ログイン機能 (プロセス分析)

<<:  MySQLは現在の日付と時刻を取得する関数

>>:  Dockerコンテナを閉じずに終了する方法の詳細な説明

推薦する

Linux で履歴コマンドを表示および実行する方法

履歴コマンドを表示し、指定されたコマンドを実行します owen@owen:~/owen/softwa...

ReactアプリケーションにおけるDOM DIFFアルゴリズムの詳細な説明

目次序文VirtualDOM とは何ですか? VirtualDOMを使用する理由DOMレンダリングペ...

Chrome タブバーを実装するための CSS のヒント

今回は、Google Chrome のタブバーのような、特殊な丸い角を持つナビゲーション バーのレイ...

Vue で手ぶれ補正を実装するためのサンプルコード

手ぶれ防止: 繰り返しのクリックによるイベントのトリガーを防止まず、揺れとは何でしょうか? 震えるの...

Vueのv-onパラメータの問題についてお話しましょう

Vue での v-on:clock の使用現在、vue.js フレームワークを学習しています。後で参...

CentOS IP接続ネットワーク実装プロセス図

1. システムにログインし、ディレクトリに入ります: cd /etc/sysconfig/netwo...

JavaScript のよりエレガントなエラー処理方法 async await

目次背景なぜエラー処理が必要なのでしょうか? async await より適切なエラー処理まとめ要約...

Linux で最も頻繁に使用されるターミナル コマンドのトップ 10 のリストを取得します。

私が最も頻繁に使用するコマンドは次の通りです:選択肢CDギットls ssh須藤数週間前、私はこの R...

CentOS 7.0 (mysql-5.7.21) で複数の MySQL インスタンスを起動する方法

設定手順Linux システム: CentOS-7.0 MySQL バージョン: 5.7.21 Lin...

Docker を使用した ElasticSearch:7.8.0 クラスターのインストールに関する詳細なチュートリアル

ElasticSearch クラスターは、クラスターを構築するための動態請求的方式と靜態配置文件をサ...

MySQL の Like の概念と使用法の説明

Like は中国語で「好き」を意味しますが、MySQL データベースに適用される場合、Like は、...

ミニプログラムカスタムコンポーネントの非効率的なグローバルスタイルの解決策

目次長すぎて読めないコンポーネントスタイルの分離デモテスト優先度ページの分離構成参考文献ネイティブ ...

JS配列の次元削減のいくつかの方法の詳細な説明

2次元配列の次元削減配列インスタンスメソッド concat と ES6 スプレッド演算子を使用した次...

Linux でファイルを削除するさまざまな方法の効率の比較

Linux で大量のファイルを削除する効率をテストします。まず500,000個のファイルを作成する$...

写真とテキストによる MySQL と sqlyog のインストール チュートリアル

1. MySQL 1.1 MySQLのインストールmysql-5.5.27-winx64 ダウンロー...