Reactフックとzarmコンポーネントライブラリ構成に基づいてh5フォームページを開発するためのサンプルコード

Reactフックとzarmコンポーネントライブラリ構成に基づいてh5フォームページを開発するためのサンプルコード

最近、React Hooks を zarm コンポーネント ライブラリと組み合わせて使用​​し、js オブジェクト構成に基づいて多数の h5 フォーム ページを開発しました。ご存知のとおり、h5 フォームの機能は、フォーム データの収集、検証、送信、エコー編集に過ぎません。通常、配置は上から下に向かって行と列に表示されます。そのため、最初から構成可能なページ生成ソリューションをカプセル化することを検討しました。現在、この構成に基づいて開発および開始されたプロジェクトが多数あります。アイデアと実装を共有しましょう。

使用シナリオ

フォームを含む任意の h5 ページ (zarm ライブラリを使用するか、独自のライブラリを適応させます)

ターゲット

  • シンプルで簡潔なコード実装
  • 構成ベース
  • 初心者でも学習コストをかけずにすぐに始められます
  • 経験豊富なユーザーにとって拡張とメンテナンスが容易

執筆前に、市場にあるいくつかのソリューションを参照しました。それらのほとんどは、JSON スキーマを定義することによって一連の形式を定義します。たとえば、Alibaba の form-render は、JSON スキーマを介してフォームを定義し、ビジュアル エディター構成を持ち、JSON ファイルをエクスポートし、動的レンダリングなどを行います。 ここでは、Ali form-render を例に、その欠点のいくつかについて説明します (利点については、公式 Web サイトの宣伝を参照してください)。

フォームレンダリングやアイデアの欠陥

1. 私のターゲットはh5です。Form-remderは現在、antdとfusionのテーマを提供するPCバックエンドフォーム構成ソリューションのみであり、デフォルトではh5をサポートしていません。

2.form-renderは拡張コンポーネントをサポートしています。内部的にマッピングテーブルを保持しており、データ型とコンポーネントのマッピング関係をマッピングしています。たとえば、antdテーマのデータ型とantdコンポーネントのマッピング関係は次のとおりです。独自のh5コンポーネントライブラリがある場合/サードパーティ企業が統一的に使用している場合、拡張機能を自分で設定する必要があり、面倒です。

// たとえば、antd でのマッピングは次のようになります。
エクスポートconstマッピング = {
 デフォルト: 'input'、
 文字列: '入力',
 配列: 'リスト',
 ブール値: 'チェックボックス',
 整数: '数値',
 番号: '番号',
 オブジェクト: 'map',
 html: 'html',
 '文字列:アップロード': 'アップロード',
 '文字列:日付': '日付',
 '文字列:dateTime': '日付',
 '文字列:時間': '日付',
 '文字列:テキストエリア': 'テキストエリア',
 '文字列:色': '色',
 '文字列:画像': '入力',
 '文字列:メール': '入力',
 '文字列:url': 'url',
 '範囲:日付': '日付範囲',
 '範囲:dateTime': '日付範囲',
 '*?enum': '選択',
 '配列?列挙': 'チェックボックス',
};

form-renderなどのjsonスキーマベースのツールを使用/開発したことがある場合、フォームフィールドの連携処理など、処理がさらに面倒な要件があります。form-renderは、ui:options、ui:disabled、ui:hiddenなど、限られた数の連携属性を提供します。このように、form-renderで定義されたデータ型、データ型テーマコンポーネントマッピング、およびコンポーネントに関連付けられたさまざまな属性に加えて、追加の連携属性も記憶する必要があります。これは、新しいプログラミング言語の複雑さを学習することに他ならないため、編集を支援する視覚的なインターフェイスが必要です。

React をインポートし、{useState} を 'react' から取得します。
'form-render/lib/antd' から FormRender をインポートします。

定数スキーマ = {
 タイプ: 'オブジェクト'、
 プロパティ:
 選択: {
  タイトル: 「シングルチョイス」
  タイプ: '文字列',
  列挙型: ['a', 'b'],
  enumNames: () => ['入力ボックスを表示', '入力ボックスを非表示'],
  'ui:disabled': (formData, rootValue) => rootValue.input1.length > 5,
  'ui:widget': 'ラジオ',
 },
 入力1: {
  タイトル: 「入力ボックス」、
  説明: '5文字以上入力してください'、
  タイプ: '文字列',
  'ui:hidden': (formData, rootValue) => formData.select === 'b',
 },
 },
};

定数Demo1 = () => {
 const [formData、setFormData] = useState({});
 戻る (
 <FormRender schema={schema} formData={formData} onChange={setFormData} />
 );
};

デフォルトのDemo1をエクスポートします。

4. この json の構成は、非開発者がフォーム機能をすばやく作成するのに適していますが、開発者が拡張機能を開発するには適していません。たとえば、2 つの入力ボックスの間にテキストと画像が混在する部分を配置したいとします。(カスタム コンポーネントを開発して別途実装する必要がありますか?)

JavaScript オブジェクト ソリューション

そのため、JSON構成を使用して動的レンダリングを実現するAli form-renderなどのソリューションは、シンプル、高速、画期的、Win-Winというコーダーの生存基準を満たすことができません。JSONをJavaScriptオブジェクトに置き換えると、構成と拡張機能が異なります。ここでは、form-renderの全体的なアイデアを引き続き使用しますが、タイプを文字列、数値、ブール値、配列、オブジェクト、htmlなどのデータ型からFunctionに変更します。Functionは、antd-mobileやzarmのInputコンポーネントなどのReactコンポーネントです。この記事はzarmに基づいているため、以下はzarmに基づいています(antd-mobileやvueなどのサードパーティのモバイル/ PC端末にも適用できます)。たとえば、次の構成です。

'react' から React をインポートします。{useState、useEffect}。
'zarm-form-render' から FormRenderer をインポートします。
'zarm' から { Input、Cell、Radio、Select、DateSelect、Button、Toast、Panel } をインポートします。

デフォルト関数App()をエクスポートする{
 const [データ、setData] = useState({});

 定数レイアウトデータ = [
 {
  タイプ: 入力、
  ラベル: '被保険者の名前'、
  プレースホルダー: '記入してください'、
  名前: '名前',
 },
 {
  タイプ: Radio.Group、
  ラベル: '性別'、
  名前: '性別',
  プロパティ: {
  タイプ: 'ボタン'、
  幽霊:本当だ、
  },
  アイテム: [
  { ラベル: '男', 値: 'male' },
  { ラベル: '女', 値: '女性' },
  ]、
 },
 {
  与える() {
  if (!data.gender) が null を返す;
  <Cell title="あなたは" description={data.gender === '男性' ? '男の子' : '女の子'}></Cell> を返します。
  },
 },
 {
  タイプ: 選択、
  ラベル: 「好きなフルーツ」
  名前: 'favfood',
  プロパティ: {
  データソース: [
   { ラベル: 'apple'、値: 'apple' },
   { ラベル: 'バナナ'、値: 'バナナ' },
  ]、
  },
 },

 {
  タイプ: DateSelect、
  ラベル: '生年月日'、
  タイトル: 「被保険者の生年月日」
  プレースホルダ: '選択してください'、
  名前: '誕生日',
  最小: '1900-01-01',
 },
 {
  タイプ: 入力、
  ラベル: '携帯電話番号'、
  プレースホルダー: '記入してください'、
  名前: 'モバイル',
 },
 {
  与える() {
  <div style={{ margin: '30px 6px',}}></div> を返します。
  },
 },
 {
  与える() {
  戻る (
   <Panel title="入力したコンテンツ">
   <div style={{ margin: '10px 6px' }}>{JSON.stringify(data)}</div>
   </パネル>
  );
  },
 },
 ];

 戻る (
 <div>
  <FormRenderer layoutData={layoutData} data={data} setData={setData} />
  <ボタン ブロック theme="primary" onClick={() => Toast.show(JSON.stringify(data))}>
  OK</ボタン>
 </div>
 );
}

フォームは配列で定義されます。オブジェクト タイプはレンダリングされるコンポーネント、名前はデータ収集のキー、その他のプロパティはコンポーネントのその他のプロパティを定義します。どのライブラリに基づいて、構成については関連するライブラリのコンポーネント API ドキュメントを参照してください。一部の特別な/存在しないコンポーネントについては、動的レンダリング用のレンダリング関数を定義します。それ以外は何も定義されていません。これらはすべて、使い慣れた React です。最後に、独自の FormRender を定義できます。これは、フォーム項目を上から下に配置する 1 次元配列 (レンダリングはフォーム項目に限定されず、任意のコンテンツをレンダリングできます)、データ収集用のデータ、およびデータ更新用の setData (React Hooks useState から派生) を受け入れます。とても簡単です。ソース コードは次のとおりです。

'react' から React をインポートします。
'zarm' から { Cell、Radio、DateSelect、Select } をインポートします。

// 設定が不可能な場合(カスタムコンポーネント、条件に基づいて表示する必要があるコンポーネントなど)は、render メソッドを使用してください。
// getJSON() は動的に json を返します
// render() カスタムレンダリング

デフォルトの関数 FormRenderer({ layoutData, data, setData }) をエクスポートします。
 const onFiledChange = (名前、値) => {
 v = 値とします。

 // 選択コントロール用
 Array.isArray(値)の場合{
  v = value.map((item) => item.value)[0];
 }

 setData({ ...データ、[名前]: v });
 };

 const onChangeFactory = (名前) => (値) => onFiledChange(名前、値);

 戻る (
 <div className="レンダラー">
  {layoutData.map((item, idx) => {
  if (typeof item.getJSON === 'function') {
   アイテム = item.getJSON();
  }
  if (typeof item !== 'object' || !item) は null を返します。
  定数{
   名前、
   タイプ、
   説明、
   アイテム、
   elProps = {},
   セルプロパティ = {},
   与える、
   ...小道具
  } = 項目;

  if (typeof render === 'function') {
   レンダリング() を返します。
  }

  children = [] とします。
  if (Array.isArray(items) && type === Radio.Group) {
   子 = items.map((it, idx1) => (
   <ラジオ値={it.value} キー={idx1}>
    {it.label}
   </ラジオ>
   ));
  }

  props.value = データ[名前];
  プロパティの onChange = onChangeFactory(名前);

  if (type === Select) {
   props.dataSource = アイテム;
  }
  if (type === DateSelect || type === Select) {
   プロパティを onOk に設定すると、プロパティが onChange になります。
   props.onChange を削除します。
   プロパティのonChange = elProps.onChange;
  }

  戻る (
   <セルキー={idx} タイトル={item.label} 説明={description} {...cellProps} 名前={name}>
   {React.createElement(type, { ...props, ...elProps }, ...children)}
   </セル>
  );
  })}
 </div>
 );
}

設定手順

'react' から * を React としてインポートします。
エクスポートインターフェースアイテム{
 type: React.Component; // Input などのコンポーネント タイプ name: string; // キー
 items?: Array<any>; // データソース
 description: string; // セルの説明
 label?: string; // セルのタイトル
 render?: () => React.ReactNode; //カスタムレンダリング
 getJSON?: () => object | null; // 動的にアイテム構成を返します elProps?: object; // コンポーネントのプロパティ構成。たとえば、タイプが Input の場合、elProps は Input に構成されます
 cellProps?: object; // セルプロパティの設定}
エクスポートインターフェースProps {
 layoutData: Array<Item>; // フォームレイアウト構成 data: object; // データストレージ、名前をキー、コンテンツを値として
 setData: () => void; // データの更新}
インターフェース FormRenderer は React.FC<Props> を拡張します {}
const FormRenderer を宣言します: FormRenderer;
デフォルトの FormRenderer をエクスポートします。

上記のコードの効果は次のとおりです。

この方法の唯一の欠点は、JSON のようにデータベースに永続的に保存できないことです。利点は、モバイルと PC のフォーム構成開発を統一し、定型コードとネストを大幅に削減し、データアクセスと検証の処理、およびフォーム項目の配置を統一できることです。

これで、React フックと zarm コンポーネント ライブラリ構成に基づいた h5 フォーム ページの開発に関するこの記事は終了です。React フックと zarm コンポーネント ライブラリの関連コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Reactフックの長所と短所
  • React Hooks の一般的な使用シナリオ (概要)
  • フックを使用して React コンポーネントを書くときに注意すべき 5 つの点
  • Reactフック入門チュートリアル
  • Reactはフックを使用して、制御されたコンポーネントの状態バインディングを簡素化します。
  • 今年最もエキサイティングな React の新機能、React Hooks を 30 分でマスターする
  • 完全なReact Hooksの練習を記録する
  • React Hooksの深い理解と使用
  • Reactフックの仕組み

<<:  mysql binlog ログを正しくクリーンアップする 2 つの方法

>>:  Dockerコンテナの紹介

推薦する

Vueはダイアログのカプセル化を実装します

目次Vue2 ライティングVue3プラグインのバージョンの記述Vue3 動的コンポーネントの記述書き...

流れと動的なライン効果を実現する純粋なCSSコード

アイデア:外側のボックスは背景を設定し、内側のボックスは背景の幅と高さを設定し、ボックスを動かすアニ...

Vueはシンプルなデータ双方向バインディングを実装します

この記事では、Vueの具体的なコード例を参考までに紹介します。具体的な内容は以下のとおりです。初心者...

React.cloneElement の使い方の詳しい説明

目次cloneElementの役割使用シナリオ新しい小道具を追加するプロップを変更するイベントカスタ...

etcd クラスターをデプロイするための docker-compose の実装手順

目次docker-compose.ymlを書くdocker-composeを実行するビルドステータス...

MySQLの浅いエントリと深いエグジットの原則についての簡単な説明

目次1. ページの概要2. 下限と上限3. ページディレクトリを使用する4. ページの実際の外観4....

Mysql InnoDBとMyISAMの違いの分析

MySQL は、myisam、innodb、memory、archive、example など、多く...

Linux 編集の開始、停止、再起動の Springboot jar パッケージ スクリプトの例

序文springboot設定ファイルでは、設定ファイルの名前には独自の意味と用途があります。 dev...

MySQL 最適化ソリューション リファレンス

最適化によって発生する可能性のある問題最適化は必ずしも単純な環境で実行されるわけではなく、実稼働環境...

MySQL ディープページング問題の解決の実践記録

目次序文ディープページングを制限すると遅くなるのはなぜですか?サブクエリによる最適化B+ツリー構造の...

VPS はオフライン ダウンロード サーバーを構築します (ネットワーク ディスクの時代以降)

モチベーション学習の必要性から、海外のサーバーメーカー(どこのメーカーかは言いません)のVPSサービ...

HTML知識ポイントの実践経験のまとめ

1. 表タグはtable、trは行、tdはセル、cellspacingはセル間の距離、cellpad...

Linux は n 日前のログとサンプルコマンドを自動的に削除します

1. ファイル削除コマンド:対応するディレクトリを検索します -mtime + 日数 -name &...

Vue3 はメッセージコンポーネントの例を実装します

目次コンポーネント設計最終的なコンポーネントAPIの定義コンポーネント構造の定義テンプレートとスタイ...

MySQL 8.0.24 リリースノートのいくつかの改善点

目次1. 接続管理2. オプティマイザレベルでの改善3. 機能の改善4. パフォーマンススキーマの最...