序文最近開発されたモバイル プロジェクトでは、Vue3 を直接使用しています。新しい機能構成 API は、まさに新しい開発体験をもたらしました。これらの機能を使用すると、開発者は高度に結合された状態とメソッドをまとめて統一的に管理したり、特定の状況に応じて再利用性の高いロジック コードを個別にカプセル化したりできるため、コード アーキテクチャ全体の堅牢性を向上させるのに非常に役立ちます。 現在、新しく開始されるモバイル プロジェクトのほとんどには、登録およびログイン モジュールが含まれています。この実践では、ログインおよび登録プロセスにおけるフォーム コントロールに関するいくつかの経験をまとめ、共通コードを抽出することでコードの保守性と開発効率を向上させました。 次に、美術科の学生が提供した写真を見てみましょう。 登録ページ ログインページ パスワードを忘れた場合のページ パスワード変更ページ 上記の製品画像を見ると、ログインおよび登録モジュール全体のコアコンポーネントは入力ボックスであることがはっきりとわかります。入力ボックスコンポーネントが完全に開発されていれば、他のページから直接参照できます。 入力ボックスが開発された後は、静的なページ表示のみが実現されます。さらに、各ページのフォーム コントロールに適用する共通のデータ検証ソリューションも設計する必要があります。 入力ボックスコンポーネント上記の分析から、入力ボックス コンポーネントがログインおよび登録モジュール全体の中核コンテンツであることがわかります。まず、入力ボックス コンポーネントの UI フォームを見てみましょう。 フォーム1 左側に「+86」というテキスト、中央に入力ボックスがあり、入力ボックスにデータが検出されると右側に十字アイコンが表示されます。データがない場合、空になり、アイコンは非表示になります。 フォーム2 左側に入力ボックスが 1 つだけあり、右側にテキストがあります。テキストの内容は、確認コード、または確認コードをクリックした後に表示されるカウントダウン テキストです。 フォーム3 左側には入力ボックスが 1 つだけ残っています。右側の入力ボックスにコンテンツがあることが検出されると、十字アイコンが表示されます。コンテンツが空の場合、アイコンは非表示になります。 レイアウト上記の観察に基づいて、この入力コンポーネントを左、中央、右の 3 つの部分に分割できます。左側にはテキストが含まれる場合もあれば、空白の場合もあります。中央は入力ボックスです。右側にはテキストまたは十字アイコンが含まれる場合があります。 テンプレートの内容は次のとおりです。 <テンプレート> <div class="input"> <!--左側、左側のコンテンツです--> <span class="left-text"> {{lt}} </span> <!--中間--> <input class="content" v-bind="$attrs" :value="値" @input="onChange" /> <!--右側の rt 判定終了は検証コードまたはクロスアイコンです--> <div v-if="rt == 'タイマー'" class="right-section"> {{ timerData.content }} <!--「確認コード」またはカウントダウンの可能性があります --> </div> <div v-else-if="rt == '閉じる'" クラス="右セクション" > <van-icon name="close" /> <!--フォークアイコン--> </div> </div> </テンプレート> レイアウトでは、左、中央、右の親要素が display:flex に設定され、3 つの子要素がすべて display:inline-block インライン ブロック モードに設定されているため、左側と右側はそれぞれのコンテンツに適応でき、中央の入力は残りの幅を埋めるために flex:1 に設定されています。 理論的には、このようなレイアウトは実現可能ですが、実際には問題が見つかりました。 デモ効果は以下のとおりです。 右側の幅が広がり続けると、デフォルトの幅が原因で中央の入力が右側にオーバーフローしてしまいますが、これは望ましいことではありません。 この問題の解決方法は非常に簡単です。中央の入力の幅を 0 に設定するだけです。次の操作で目的の効果が得られます。 vモデル外部ページによって参照される上記パッケージのコンポーネント構造は次のとおりです。 <入力フォーム lt="+86" <!--+86 は左側に表示されます--> rt="close" <!-- 右側に十字アイコンが表示されます --> placeholder="携帯電話番号を入力してください" /> 外部ページでは以下のようにフォームデータ form_data を作成しますが、form_data のデータは v-model を介して子コンポーネントの入力ボックスの値に双方向にバインドできることが期待されます。 定数form_data = リアクティブ({ number_number: '', //usernamepassword: '', //passwordppassword: '', //passwordrepeatcaptcha: '', //verification code}) vue3 で v-model を実装するのは非常に簡単です。親コンポーネントで v-model:xx を使用してバインディングを完了します。ここで、xx は、以下に示すように、子コンポーネントがバインドされている状態名に対応します。 <入力フォーム lt="+86" <!--+86 は左側に表示されます--> rt="close" <!-- 右側に十字アイコンが表示されます --> placeholder="携帯電話番号を入力してください" v-model:value="form_data.password" /> 次に、子コンポーネントで、まずバインドする属性値を宣言し、入力ボックスの oninput イベントをリッスンします。コードは次のとおりです。 <テンプレート> <div class="input"> ... <input class="content" v-bind="$attrs" :value="値" @input="onChange" /> ... </div> </テンプレート> エクスポートデフォルトdefineComponent({ 小道具: { lt:文字列、 rt: 文字列、 値: 文字列 }, セットアップ(プロパティ、コンテキスト) { 定数 onChange = (e:KeyboardEvent) => { const value = (e.target を HTMLInputElement として).value; context.emit("update:value",値); }; 戻る { 変更時 } } }) oninput イベントのコールバック関数は、context.emit("update:value",value) を使用して取得した値を返します。 update:value の前半部分は固定の文言で、後半に双方向バインドする状態名を記入します。このようにして、v-model のバインディングが簡単に完成します。 データ検証一般的に言えば、ページにフォーム コントロール (入力ボックスなど) がある限り、対応する値に対してデータ検証を実行する必要があります。元の方法に従うと、ユーザーがボタンをクリックすると、js は応答を受け取り、各フォーム項目の値を順番に取得して検証します。 このアプローチは確かに機能を実現できますが、効率的で簡潔ではありません。多くのページを検証する必要があるため、多くの検証ロジックが繰り返し記述されます。 次に、再利用可能なロジック コードをカプセル化し、各ページにすばやく適用して開発効率を向上させるためのユニバーサル検証ソリューションを設計します。 登録ページを例にとると、テンプレートコードは次のようになります。携帯電話番号、携帯電話認証コード、パスワード、パスワードの確認の 4 つの入力ボックスコンポーネントを作成します。最後に、登録ボタンを配置します。(見栄えを良くするために、次のコードではすべての ts タイプを削除します) <フォーム ref="フォーム" :rules="ルール"> <入力フォーム +86 円 rt="閉じる" v-model:value="フォームデータ.number_number" placeholder="携帯電話番号を入力してください" propName="数値_数値" /> <入力フォーム rt="タイマー" v-model:value="form_data.captcha" placeholder="モバイル認証コードを入力してください" propName="キャプチャ" /> <入力フォーム rt="閉じる" v-model:value="form_data.password" placeholder="パスワードを入力してください" タイプ=「パスワード」 propName="パスワード" /> <入力フォーム rt="閉じる" v-model:value="form_data.ppassword" placeholder="確認パスワードを入力してください" タイプ=「パスワード」 propName="ppassword" /> <Button text="登録" @sub="onSubmmit" /> <!--登録ボタン--> </フォーム> 他の優れたフレームワークのフォームの実践から学んだ後、最初に最外層にコンポーネント Form を追加し、次に各入力ボックス コンポーネントにプロパティ propName を追加しました。このプロパティは、rules と一緒に使用されます。rules は手動で定義された検証ルールです。これが Form コンポーネントに渡されると、子コンポーネント (入力ボックス コンポーネント) は propName プロパティを通じて検証ルールを取得できます。 全体的な実装のアイデアは、最初から接続できます。まず、フロントエンド開発者が現在のページの検証ルールを定義し、それをフォーム コンポーネントに渡します。フォーム コンポーネントはそれを受け取った後、検証ルールを各サブコンポーネント (入力ボックス コンポーネント) に配布します。サブコンポーネントは検証ルールを取得した後、入力ボックスの値に対して対応するデータ検証を実行できます。 ユーザーが登録ボタンをクリックすると、クリック イベントによって Form コンポーネントのインスタンスが取得され、その検証メソッドが実行されます。このとき、Form コンポーネントは各サブコンポーネントに対して一連のデータ検証を実行します。すべての検証が成功すると、検証メソッドは true を返します。検証に失敗すると、検証メソッドは false を返し、エラー メッセージをポップアップ表示します。 登録ページのロジックは次のとおりです。 エクスポートデフォルトdefineComponent({ コンポーネント: InputForm、//入力ボックスButton、//登録ボタンForm、//フォームコンポーネント}、 セットアップ(プロパティ) { const form_data = ...; // 省略 const rules = ...; // 最も外側の Form コンポーネントのインスタンスを取得します。const form = ref(null); 定数onSubmit = ()=>{ if (!form.value || !form.value.validate()) { false を返します。 } //検証に合格したら、登録インターフェースをリクエストできます} 戻る { 形状、 ルール、 送信時、 フォームデータ }; }, }); 変数フォームを定義し、それを使用して Form フォームのインスタンスを取得します。テンプレート <Form ref="form" :rules="rules"> に、ref 属性を追加するだけです。 ユーザーが登録ボタンをクリックして onSubmit 関数をトリガーします。form は ref を使用して作成された変数であるため、値を取得するには .value を呼び出す必要があります。form.value.validate() 関数を実行して、Form フォームの下の各サブコンポーネントの検証ロジックの実行を開始します。すべてが合格した場合は true が返され、1 つでも不合格の場合は false が返されます。 上記の分析から、フォーム コントロールは検証関数のみを公開しており、この関数を呼び出すことで検証が成功したかどうかを知ることができることがわかります。では、検証は検証に使用するルールをどのように知るのでしょうか。まず検証ルールのセットを設計し、それをフォーム コンポーネントに渡す必要があります。その後、その内部検証関数がルールを使用して検証を実行できます。 ルール設計ルールはオブジェクトです。たとえば、上記の登録ページのルールは次のように定義されています。 定数ルール = { 番号_番号:[{ タイプ: '必須'、 メッセージ:"有効な電話番号を入力してください" } "電話" ]、 キャプチャ:[ { タイプ: '必須'、 メッセージ: '認証コードは空欄にできません' } ]、 パスワード: [ { タイプ: '必須'、 メッセージ: 'パスワードを入力してください', }, { タイプ: 'minLength'、 パラメータ: 6, メッセージ: 'パスワードの長さは6文字未満にできません', }, ]、 パスワード:[ { タイプ: 'custome'、 折り返し電話() { form_data.password !== form_data.ppassword の場合 { 戻る { フラグ: false、 メッセージ: 「入力した 2 つのパスワードが一致しません」 }; } 戻る { フラグ: true、 }; }, }, ] } 定義したルールは、キーと値のペアの形式のオブジェクトです。キーはテンプレート上の各入力ボックス コンポーネントの propName に対応し、値は入力ボックス コンポーネントが従う必要があるルールに対応する配列です。 次に、各オブジェクトの下の値の構成を詳しく見てみましょう。値が配列に編成されているのは、入力ボックスに複数のルールを追加できるためです。ルールは 2 つの形式に対応しており、1 つはオブジェクトで、もう 1 つは文字列です。 文字列は理解しやすいです。たとえば、上記の number_number 属性は文字列 phone に対応しています。このルールの意味は、入力ボックスの値が携帯電話番号のルールに準拠する必要があるということです。もちろん、文字列に email が入力されている場合は、メールアドレスとして検証する必要があります。 ルールがオブジェクトの場合、次のプロパティが含まれます。 { type, // タイプ msg, // カスタム エラー メッセージ params, // 渡されるパラメータ値 (例: {type:'minLength',params:6})、値の最小長は 6 桁未満にできません callback // カスタム検証関数} type は検証タイプです。required と入力されている場合は、必須フィールドであることを意味します。ユーザーが入力しない場合は、登録ボタンをクリックして送信するときに、msg で定義されたエラー メッセージが報告されます。 さらに、type は minLength または maxLength を入力して値の長さを制限することもできます。何桁まで制限できますか? これは params を通じて渡すことができます。 最後に、type を custome として入力することもできます。これにより、開発者は入力ボックスの検証ロジック関数コールバックを定義できます。関数は、最後に flag 属性を持つオブジェクトを返す必要があります。属性 flag はブール値であり、検証が成功したか失敗したかを検証システムに伝えます。 形状ルールが定義された後、それらはフォーム コンポーネントに渡されます。フォーム コンポーネントは、検証ロジックをサブコンポーネントに配布する必要があります。各サブコンポーネントが独自の検証関数を生成するようにします。 <!-- フォーム コンポーネント --> <テンプレート> <div class="form"> <スロット></スロット> </div> </テンプレート> <script lang="ts"> 「vue」から ref、provide をインポートします。 エクスポートデフォルトdefineComponent({ 名前: "フォーム", 小道具:{ ルール:オブジェクト }, セットアップ(プロパティ) { ...// provide("rules", props.rules); を省略 // 検証ルールを配布 const valid = ()=>{ //公開された検証関数} 戻る { 検証する } } }) </スクリプト> 上記の構造からわかるように、フォーム コンポーネント テンプレートはスロット関数を提供し、ロジック コードで provide を使用して子孫に検証ルールを渡し、検証関数を公開します。 サブコンポーネントは検証関数を生成する今回は、ログインおよび登録モジュールのコア コンポーネント InputForm に戻ります。次に、入力ボックス コンポーネントに検証ロジックを追加する必要があります。 「vue」から { inject, onMounted } をインポートします。 ... セットアップ(プロパティ、コンテキスト) { const ルール = inject("ルール"); const rule = rules[props.propName]; // propNameを通じて検証ルールを取得する const useValidate = () => { const validFn = getValidate(rule); // 検証関数を取得する const execValidate = () => { return validFn(props.value); //検証関数を実行し、検証結果を返します}; マウント時(() => { const リスナー = inject('collectValidate'); if (リスナー) { リスナー(execValidate); } }); }; useValidate(); //検証ロジックを初期化します... } ルールの構造は次のようになります。inject と propName を通じて、Form が入力ボックスに配布して実行するルールを取得できます。 { キャプチャ:[{ タイプ: '必須'、 メッセージ: '認証コードは空欄にできません' }], パスワード:[{ タイプ: '必須'、 メッセージ: 'パスワードを入力してください', }] } 次に、後述のgetValidate関数にルールruleを渡して検証関数validateFnを取得します。検証関数validateFnは入力ボックスの値を渡して検証結果を返します。ここではvalidateFnをカプセル化してexecValidateに渡して外部で利用できるようにします。 上記のコードでは、ロジック コードが onMounted でラップされていることもわかります。コンポーネントがマウントされると、inject を使用して Form コンポーネントから渡された関数 Listener を取得し、検証関数 execValidate をパラメーターとして渡して実行します。 以下のコードの Form コンポーネントに戻り、Listener がどのような機能であるかを確認しましょう。 セットアップ(プロパティ) { const list = ref([]); //配列を定義する const listener = (fn) => { リスト.値.プッシュ(fn); }; provide("collectValidate", listener); // リスニング関数を配布 // 検証関数 const validate = (propName) => { 定数配列 = list.value.map((fn) => { fn() を返します。 }); const one = array.find((item) => { item.flag === false を返します。 }); if (one && one.msg) { //検証に失敗しました Alert(one.msg); //ポップアップエラーメッセージ return false; } それ以外 { true を返します。 } }; ... 上記のように、Form コンポーネントはリスナー関数を配布します。onMounted ライフサイクル フックでは、サブコンポーネントが配布されたリスナー関数を取得し、サブコンポーネントで定義されている検証関数 execValidate をパラメーターとして渡して実行します。 これにより、各サブコンポーネントがマウントされると、その検証関数が Form コンポーネントのリスト コレクションに渡されるようになります。Form コンポーネントの検証メソッドは、リストをループして各サブコンポーネントの検証関数を順番に実行するだけで済みます。すべての検証に合格すると、外部ページに true が返されます。1 つでも失敗すると、エラー メッセージがポップアップ表示され、false が返されます。 この時点で、検証プロセス全体が完了しています。フォームは最初に検証ルールをサブコンポーネントに配布し、サブコンポーネントはルールを取得して独自の検証関数を生成し、検証関数がマウントされた後にコレクションのためにフォームに返します。この時点で、フォーム コンポーネントによって公開される検証関数は、すべてのフォーム コントロールのデータ検証を実装できます。 次の最後のステップは、サブコンポーネントがルールを通じて独自の検証関数を生成する方法を調べることです。 チェックまず、検証ロジックを管理する Validate クラスを作成します。コードは次のとおりです。email メソッドや maxLength メソッドの追加など、新しい要件に応じてこのクラスのメソッドを拡張し続けることができます。 クラス Validate { コンストラクタ() {} required(data) { //必須かどうか確認 const msg = 'この情報は必須です'; //デフォルトのエラーメッセージ if (data == null || (typeof data === 'string' && data.trim() === '')) { 戻る { フラグ:false、 メッセージ } } 戻る { フラグ:true } } // 携帯電話番号かどうか確認する phone(data) { const msg = '正しい携帯電話番号を入力してください'; //デフォルトのエラーメッセージ const flag = /^1[3456789]\d{9}$/.test(data); 戻る { メッセージ、 フラグ } } // データの最小長をチェックする minLength(data, { params }) { let minLength = params; // 最小長 if (data == null) { 戻る { フラグ:false、 メッセージ: 「データは空にできません」 } } (data.trim().length >= minLength)の場合{ {フラグ:true} を返します。 } それ以外 { 戻る { フラグ:false、 msg:`データの最小長は ${minLength} ビット未満にすることはできません` } } } } Validate クラスで定義されたすべてのメソッドでは、最初のパラメーター データは検証される値であり、2 番目のパラメーターはページの各ルールで定義されたルールです。たとえば、{type: 'minLength'、params: 6、msg: 'パスワードの長さは 6 文字未満にすることはできません'}。 Validate クラスの各メソッドによって返されるデータ構造は、{flag:true,msg:""} の形式です。結果では、flag は検証が合格したかどうかを示し、msg はエラー メッセージです。 検証クラス Validate は、さまざまな検証メソッドを提供します。次に、シングルトン パターンを使用してこのクラスのインスタンスを生成し、インスタンス オブジェクトを実際の検証シナリオに適用します。 const getInstance = (関数(){ _instance を作成します。 関数()を返す{ if(_instance == null){ _instance = 新しい検証(); } _instance を返します。 } })() getInstance 関数を呼び出すと、シングルトン Validate インスタンス オブジェクトを取得できます。 入力ボックス コンポーネントは、getValidate 関数にルールを渡すことで、コンポーネントに必要な検証関数を返すことができます。次に、getValidate 関数がルールを通じて検証関数を生成する方法を見てみましょう。コードは次のとおりです。 /** * 検証関数を生成する */ エクスポートconst getValidate = (ルール) => { const ob = getInstance(); //Validate クラスのインスタンス オブジェクトを取得します const fn_list = []; //すべての検証関数を収集します //ルール配列を走査し、Validate クラス内の検証メソッドをそのタイプに応じて取得し、fn_list に入れて収集します rule.forEach((item) => { if (typeof item === 'string') { // 文字列型 fn_list.push({ fn: ob[項目], }); } else if (isRuleType(item)) { // オブジェクト型 fn_list.push({ //item.type がカスタム タイプの場合、検証関数はコールバックを直接使用します。それ以外の場合は、ob インスタンスから item を取得します。 fn: item.type === 'custome' ? item.callback : ob[item.type], }); } }); //返される必要がある検証関数 const execuate = (value) => { フラグをtrueにし、 メッセージ = ''; (i = 0 とします; i < fn_list.length; i++) { 定数項目 = fn_list[i]; const result = item.fn.apply(ob, [value, item]); //item.fnはValidateクラスで定義された検証メソッドに対応します。if (!result.flag) { //検証失敗フラグ = false; msg = item.msg ? item.msg : result.msg; // デフォルトのエラー メッセージを使用するか、ユーザー定義のメッセージを使用するか break; } } 戻る { フラグ、 メッセージ、 }; }; 実行を返します。 }; ルールのデータ構造は次のコードのようになります。ルールが getValidate 関数に渡されると、それがオブジェクトか文字列かが判断され、その型に対応する検証関数が ob インスタンスから取得され、fn_list に格納されます。 [ { タイプ: '必須'、 メッセージ: 「電話番号を入力してください」 }, "電話" ] getValidate 関数は最終的に実行関数を返しますが、これは入力ボックス コンポーネントによって取得される検証関数でもあります。入力ボックスの値は入力ボックス コンポーネントで取得できます。execute メソッド呼び出しに値が渡されると、メソッドは以前にキャッシュされた検証関数リスト fn_list をトラバースし、実行する各検証メソッドに値を渡してから、現在の値に対する入力ボックス コンポーネントの検証結果を取得して返します。 上記の検証ロジックが実装されました。次に、ログイン ページ、パスワードを忘れた場合のページ、パスワードを変更した場合のページを開発する場合は、Form コンポーネントと InputForm コンポーネントを使用してページ構造を整理し、現在のページのルール セットを記述するだけです。残りの検証の詳細と対話型アクションはすべて、Form と InputForm によって内部的に処理されるため、開発効率が大幅に向上します。 最終結果要約するこれで、vue3 でモバイル ログインおよび登録モジュールをエレガントに実装する方法に関するこの記事は終了です。vue3 モバイル ログインおよび登録モジュールの関連コンテンツの詳細については、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySQL5.7.18winX64のWin10インストールでサーバーの起動に失敗し、エラーメッセージも表示されない
>>: Docker ベースの Etcd 分散デプロイメントの方法と手順
WeChat ミニプログラムのネイティブ コンポーネントであるカメラ、キャンバス、入力 (フォーカス...
1. インデックスの役割一般的に言えば、インデックスは本の目次に相当します。条件に基づいてクエリを実...
効果: CSS スタイル: <スタイル タイプ="text/css">...
効果画像(三角形をご希望の場合は、ここをクリックしてください): コード: <html>...
目次tf-gpu をダウンロード取得したtf-gpuイメージに基づいて独自のイメージを構築するイメー...
序文最近CocosCreatorを学びたいと思ったので、エディターをダウンロードして起動しました。誰...
LIKE 演算子は、列内の指定されたパターンを検索するため、WHERE 句で使用されます。文法: 列...
1. まずmysqlサービスを停止します管理者としてCMDを開いて閉じるか、Windowsサービスペ...
方法 1: Google の詳細検索を使用します。たとえば、次に示すように.asp?id=9などの ...
この記事の例では、Vueの具体的なコードを共有し、zipファイルをダウンロードして参考にしています。...
この記事では、大画面スクロール効果を実現するためのjQueryの具体的なコードを参考までに紹介します...
Oracle、DB2、SQL Server などの他の大規模データベースと比較すると、MySQL に...
これは Linux 管理者にとって重要な (そして素晴らしい) トピックなので、誰もが Linux ...
目次非同期とは何ですか?なぜ非同期性が必要なのでしょうか?非同期IOとは何ですか?イベントループとは...
Mysql でよく使用される表示コマンド1. 現在のデータベース サーバー内のデータベースの一覧を表...