JSX を使用してマークアップ コンポーネント スタイルの開発を作成する例 (フロントエンドのコンポーネント化)

JSX を使用してマークアップ コンポーネント スタイルの開発を作成する例 (フロントエンドのコンポーネント化)

ここでは、コンポーネント システムをゼロから構築します。まず、前回の記事「フロントエンドのコンポーネント化の基礎」と「JSX を使用してコンポーネント パーサーを確立する」から、コンポーネントはマークアップと JavaScript を通じてアクセスできる環境であることがわかります。

したがって、最初のステップは、マークアップを使用できる環境を作成することです。ここでは、JSX を使用してマークアップのスタイルを設定する方法を学習します。ここでは、React と同じ JSX を使用してコンポーネントのスタイルを設定します。


JSX環境の構築

一般的に、JSX は React の一部であると考えられています。実際、Facebook は JSX を純粋な言語拡張として定義しています。また、この JSX は他のコンポーネント システムでも使用できます。

HTML タグを素早く作成する方法としても使用できます。

プロジェクトの設定

それでは、基本から始めましょう。まず、新しいプロジェクト ディレクトリを作成する必要があります。

mkdir jsx コンポーネント

NPMを初期化する

もちろん、このプロジェクト フォルダーは任意のディレクトリに作成します。フォルダーを作成したら、そのディレクトリに入り、 npmを初期化できます。

npm 初期化

上記のコマンドを実行すると、いくつかのプロジェクト設定オプションが表示されます。必要に応じて入力してください。ただし、Enter キーを押し続けることもできます。その後、必要な学生がpackage.jsonを開いて、自分で変更することもできます。

webpackをインストールする

多くの学生は Wepack について知っているはずです。Wepack は、通常の JavaScript ファイルを、さまざまな import ファイルと require ファイルを一緒にパッケージ化できるファイルに変換するのに役立ちます。

そのため、 webpackをインストールする必要があります。もちろん、npx を使用して webpack を直接使用することも、webpack-cli をグローバルにインストールすることもできます。

ここでは、webpack-cli のグローバル インストールを使用します。

npm インストール -g webpack webpack-cli

インストールが完了したら、次のコマンドを入力して、インストールされている webpack のバージョンを確認できます。実行後にエラーがなく、バージョン番号が表示されれば、正常にインストールされたことが証明されます。

webpack --version

Babelをインストールする

JSX は babel プラグインなので、webpack、babel-loader、babel、babel プラグインを順番にインストールする必要があります。

ここでの Babel のもう 1 つの用途は、新しいバージョンの JavaScript を古いバージョンの JavaScript にコンパイルできるため、より古いバージョンのブラウザーでの実行をサポートできることです。

Babel をインストールするには、次のコマンドを実行するだけです。

npm インストール --save-dev webpack babel-loader

ここで注意する必要があるのは、開発依存関係に babel を追加するために--save-devを追加する必要があることです。

実行後、上の画像のようなメッセージが表示されます。

正しくインストールされたことを確認するには、プロジェクト ディレクトリのpackage.jsonを開きます。

{
 "名前": "jsx-コンポーネント",
 "バージョン": "1.0.0",
 "説明": ""、
 "メイン": "index.js",
 「スクリプト」: {
 "test": "echo \"エラー: テストが指定されていません\" && exit 1"
 },
 "著者": ""、
 「ライセンス」: 「ISC」、
 「devDependencies」: {
 "バベルローダー": "^8.1.0",
 "ウェブパック": "^5.4.0"
 }
}

OK、 devDependenciesの下に、先ほどインストールした 2 つのパッケージが確かにあることがわかります。それでも心配な場合は、 package.jsonもう一度確認してください。

webpackを設定する

この時点で、webpack 構成を構成する必要があります。 webpack を構成するには、 webpack.config.js構成ファイルを作成する必要があります。

プロジェクトのルート ディレクトリにwebpack.config.jsファイルを作成します。

まず、webpack config は nodejs モジュールなので、その設定を記述するには module.exports を使用する必要があります。これは、初期の Node.js ツールの一般的な構成方法です。JavaScript ファイルを使用して構成するため、構成にロジックを追加できます。

モジュール.エクスポート = {}

Webpack の最も基本的なことは、エントリを設定する (エントリ ファイルを設定する) 必要があることです。ここではmain.jsをセットアップしました。

モジュール.エクスポート = {
 エントリ: "./main.js"
}

この時点で、まずルート ディレクトリにmain.jsファイルを作成できます。まず、内部に簡単なforループを追加しましょう。

// main.js ファイルの内容 for (let i of [1, 2, 3]) {
 コンソールにログ出力します。
}

このようにして、webpack の基本構成が構成されました。ルート ディレクトリで webpack を実行して、 main.jsファイルをパッケージ化して確認してみましょう。次のコマンドを実行するだけです。

ウェブパック

実行が完了すると、コマンドライン インターフェイスに上記のようなプロンプトが表示されます。

細かいことに気を配る生徒は必ず手を挙げて質問するでしょう、クラスメイト!コマンドラインにエラーがあります。黄色の部分では警告が表示されますが、問題はありません。次の構成で修正されます。

この時点で、ルート ディレクトリに新しいフォルダーdistが生成されていることがわかります。これは、webpack によってデフォルトで生成されるフォルダーです。パッケージ化されたすべての JavaScript とリソースは、デフォルトでこのフォルダーに配置されます。

ここで、 distフォルダーにパッケージ化されたmain.jsファイルがあることがわかります。これは、webpack によってパッケージ化された、私たちが作成したmain.jsです。

次にそれを開くと、babel によってコンパイルされた後の JavaScript コードが表示されます。数行のコードに多くのものが追加されていることに気づくでしょうが、これらについては心配する必要はありません。これが Webpack の「ニャーパワー」です。

コードの最後には、先ほど書いたforループがまだ残っていますが、少し変更されているだけで、機能は同じです。

Babel-loaderをインストールする

次に、babel-loader をインストールしましょう。実は、babel-loader は babel に直接依存していないので、 @babel/core@babel/preset-env別途インストールする必要があります。インストールするには、次のコマンド ラインを実行するだけです。

npm をインストール --save-dev @babel/core @babel/preset-env 

最終結果は上記の通りであり、インストールが成功したことが証明されます。この時点で、パッケージ化時に babel-loader を使用できるように、 webpack.config.jsで設定する必要があります。

上記で設定したwebpack.config.jsentryの後に、 moduleというオプションを追加します。

次に、ビルド時に使用するrulesモジュールに追加することもできます。 rules配列型の構成であり、ここでの各ルールはtestuseで構成されます。

  • テスト:

testの値は、このルールを使用する必要があるファイルを照合するために使用される正規表現です。ここではすべての JavaScript ファイルを一致させる必要があるため、 /\.js/を使用できます。

  • 使用:

ローダー: babel-loaderの名前を追加するだけです

  • オプション:

プリセット:

  • ここにローダーオプションがあります。ここで@babel/preset-envを追加する必要があります。

最終的に、構成ファイルは次のようになります。

モジュール.エクスポート = {
 エントリ: './main.js',
 モジュール: {
 ルール:
 {
 テスト: /\.js$/,
 使用: {
 ローダー: 'babel-loader',
 オプション:
 プリセット: ['@babel/preset-env'],
 },
 },
 },
 ]、
 },
};

これを設定したら、babel を実行して試してみます。前と同じように、コマンドラインでwebpackを実行するだけです。

設定ファイルが正しく記述されていれば、上図のような結果が表示されるはずです。

次に、 distフォルダーに移動し、コンパイルされたmain.jsを開いて、今回は babel-loader を使用した後のコンパイル結果を確認します。

コンパイル後、 for of of ループが通常のforループにコンパイルされていることがわかります。これは、babel-loader が効果的であり、新しいバージョンの JavaScript 構文を古いブラウザと互換性のある JavaScript 構文に正しくプログラムしていることも証明しています。

この時点で、JSX に必要な環境がインストールおよび構築されました。

モード設定

最後に、webpack.config.js に環境設定を追加する必要がありますが、これはオプションと言えますが、日常の開発の利便性のために行います。

そのため、webpack.config.js にmodeを追加し、このプロパティの値としてdevelopmentを使用する必要があります。この構成は、開発者モードであることを示します。

一般的に、コード リポジトリに記述する webpack 構成では、このmode: 'development'構成がデフォルトで追加されます。実際にリリースする際には、 mode: 'production'に変更します。

モジュール.エクスポート = {
 エントリ: './main.js',
 モード: '開発'、
 モジュール: {
 ルール:
 {
 テスト: /\.js$/,
 使用: {
 ローダー: 'babel-loader',
 オプション:
 プリセット: ['@babel/preset-env'],
 },
 },
 },
 ]、
 },
};

変更後、 webpackを使用してコンパイルし、 main.jsの違いを確認します。

明らかに、コンパイルされたコードは 1 行に圧縮されていないことがわかりました。この方法で、webpack によって生成されたコードをデバッグできます。ここで、 main.jsのコードが文字列に変換され、 eval()関数に配置されていることがわかります。コードはevalに配置されているため、デバッグ時に別のファイルとして使用できます。

JSXのインポート

東風を除いて、すべて準備が整いました。最後に、JSX をどのように導入するのでしょうか?インポートする前に、現在の構成でmain.jsで JSX 構文を使用した場合に何が起こるかを確認しましょう。プログラマーとして、私たちは常に少し冒険心を持つ必要があります。

そこで、次のコードをmain.jsに追加します。

var a = <div />

それでは、webpack を実行して確認してみましょう。

よくやった!案の定、エラーが報告されました。ここでのエラーは、「小なり記号」は=の後には使用できないことを示していますが、通常の JSX 構文では、これは実際には HTML タグの「山括弧」です。JSX 構文のコンパイル プロセスがないため、JavaScript はデフォルトでこれを「小なり記号」であると想定します。

では、Webpack コンパイル プロセスで JSX 構文をサポートするにはどうすればよいでしょうか?ここで実際に最も重要なパッケージを追加する必要がありますが、このパッケージの名前は@babel/plugin-transform-react-jsxという非常に長い名前です。さて、このパッケージをインストールするコマンドを実行してみましょう。

npm をインストール --save-dev @babel/plugin-transform-react-jsx

インストール後、webpack 構成にも追加する必要があります。 module内のrulesuse plugins設定に['@babel/plugin-transform-react-jsx']を追加する必要があります。

最終的に、webpack 構成ファイルは次のようになります。

モジュール.エクスポート = {
 エントリ: './main.js',
 モード: '開発'、
 モジュール: {
 ルール:
 {
 テスト: /\.js$/,
 使用: {
 ローダー: 'babel-loader',
 オプション:
 プリセット: ['@babel/preset-env'],
 プラグイン: ['@babel/plugin-transform-react-jsx'],
 },
 },
 },
 ]、
 },
};

設定が完了したら、webpack を実行してみましょう。この時点で、エラーは発生していないことがわかりました。これは、コードが JSX 構文を使用した記述をサポートするようになったことを証明しています。

最後に、プログラミングの最終的な効果を見てみましょう。

evalに追加した<div/> React.createElement("div", null)の関数呼び出しに変換されていることがわかります。

それでは、 React.createElementどのように実装すべきか、またそれを独自の関数名に置き換えることができるかどうかを見てみましょう。

基本的な JSX の使用法

まず、JSX を理解してみましょう。JSX は実際にはコード構文の単なるショートカットです。前のセクションの最後で、JSX 構文がコンパイルされた後、 React.createElementへの呼び出しが表示されることを確認しました。

JSXの基礎

ここではまず、webpack の JSX プラグインを変更し、カスタム要素作成関数名を付けます。 webpack.config.js を開き、プラグイン セクションで変更します。

モジュール.エクスポート = {
 エントリ: './main.js',
 モード: '開発'、
 モジュール: {
 ルール:
 {
 テスト: /\.js$/,
 使用: {
 ローダー: 'babel-loader',
 オプション:
 プリセット: ['@babel/preset-env'],
 プラグイン: [
				[
					'@babel/plugin-transform-react-jsx',
					{ プラグマ: 'createElement' }
				]
			]、
 },
 },
 },
 ]、
 },
};

上記では、元の['@babel/plugin-transform-react-jsx']パラメータ[['@babel/plugin-transform-react-jsx', {pragma: 'createElement'}]] 。このpragmaパラメータを追加することで、作成する要素の関数名をカスタマイズできます。

この変更により、JSX は React フレームワークとは何の関係もなくなります。 webpack を実行して、最終的に生成された効果を確認してみましょう。React.createElement React.createElement createElementになることがわかります。

次に、main.js を実行するための HTML ファイルを追加して試してみます。まず、ルート ディレクトリにmain.htmlを作成し、次のコードを入力します。

<script src="./main.js"></script>

次に、この HTML ファイルを実行してブラウザで開きます。

この時点で、コンソールにエラーが表示され、 createElement未定義になります。実際、この関数はmain.jsで定義されていないため、見つかりません。

したがって、 createElement関数を自分で記述する必要があります。ルート ディレクトリでmain.jsを直接開き、前のforループを削除して、次のコードを追加します。

関数createElement() {
 戻る;
}

a = <div /> とします。

ここでは、空を返して、この関数を最初に呼び出し可能にします。 webpack で一度再コンパイルし、main.html ページを更新します。この時点ではエラーは発生せず、正常に実行できることがわかります。

createElement関数の実装

コンパイルされたコードでは、JSX 要素が createElement を呼び出すときに 2 つのパラメータを渡すことがわかります。最初の引数はdiv 、 2 番目の引数はnullです。

ここで 2 番目のパラメータがnullなのはなぜですか?実際、2 番目のパラメータは属性リストを渡すために使用されます。 main.js の div にid="a"を追加すると、最終的なコンパイルでどのような変更が行われるか確認してみましょう。

2 番目のパラメータは、Key-Value モードで保存された JavaScript オブジェクトになることがわかります。今考えてみると、JSX はそれほど神秘的なものではありません。これは、通常記述する HTML を JavaScript オブジェクトにコンパイルするだけです。一種の「構文糖」と考えることができます。

しかし、JSX はコードの構造に影響を与えるため、通常はこれを構文糖衣とは呼びません。

次に、より複雑な JSX を記述してみましょう。元の div にいくつかの子要素を追加します。

関数createElement() {
 戻る;
}

a = (とする
 <div id="a">
 <span></span>
 <span></span>
 <span></span>
 </div>
);

最後に、webpack パッケージ化を実行して効果を確認しましょう。

コンソールでは、最終的なコンパイル結果がcreateElement関数への再帰呼び出しであることがわかります。実際、ここにはツリー構造が形成されています。

親は第 1 レベルの div 要素であり、子は最初の createElement 関数に渡されるパラメーターです。次に、スパンに属性がないため、後続のすべての createElements の 2 番目のパラメーターはnullなります。

ここで表示されるコンパイル結果に基づいて、createElement 関数のパラメータが何であるべきかを分析できます。

  • 最初のパラメータtypeは、このタグのタイプです
  • 2番目のパラメータattribute - タグ内のすべての属性と値
  • 残りのパラメータはすべて子プロパティです...children - ここではJavaScriptの比較的新しい構文を使用します...children次のすべてのパラメータ(不定数)が配列に変換され、children変数に割り当てられることを意味します

次に、 createElement関数は次のように記述できます。

関数createElement(type, 属性, ...children) {
 戻る;
}

機能はありますが、この機能では何ができるのでしょうか?実はこの関数は何にでも使えます。DOM API のように見えるので、React とはまったく関係のないエンティティ DOM にすることもできます。

たとえば、この関数ではこのtypeelementを返すことができます。ここで、渡されたすべてのattributesこの要素に追加し、この要素に子要素を添付することができます。

要素を作成するにはcreateElement(type)を使用し、属性を追加するにはsetAttribute()を使用し、最後に子要素を追加するにはappendChild()を使用します。

関数createElement(type, 属性, ...children) {
 // 要素を作成します。let element = document.createElement(type);
 // 属性をハングする for (let attribute in attributes) {
 要素.setAttribute(属性);
 }
 // すべての子要素をハングする for (let child of children) {
 要素.appendChild(子);
 }
 //最終的に要素はノードなので、直接返すことができます return element;
}

ここではcreateElement関数のロジックを実装します。最後に、ページに DOM ノードをマウントする必要もあります。本体に直接取り付けることが可能です。

// このコードをmain.jsの末尾に追加します。let a = (
 <div id="a">
 <span></span>
 <span></span>
 <span></span>
 </div>
);

ドキュメント本体に子要素を追加します。

ここで、main.html に body タグがないことに留意してください。そうしないと、body にマウントできません。したがって、ここで main.html に body タグを追加する必要があります。

<本文></本文>
<script src="dist/main.js"></script>

さて、これで webpack でパッケージ化して効果を確認できます。

素晴らしい!ノードを生成し、ボディに取り付けることができました。しかし、 divにテキストを追加すると、テキスト ノードがcreateElement関数に渡されます。言うまでもなく、 createElement関数は現在のロジックではテキスト ノードを処理できません。

次に、テキスト ノードを処理するロジックを追加しますが、その前に div 内の span タグを削除し、テキスト「hello world」に置き換えます。

a = <div id="a">hello world</div> とします。

テキスト ノードのロジックを追加する前に、まずは webpack でパッケージ化しましょう。子ノードをハングアップする前に、具体的にどのようなエラーが報告されるかを確認しましょう。

まず、 createElement関数が呼び出される場所で、テキストが文字列として渡され、このパラメーターが子ノードを受け取り、ロジックでは DOM ノードを受け取るappendChild使用していることがわかります。明らかに、テキスト文字列はノードではないので、エラーが報告されます。

このデバッグ方法により、関数を実装するためにロジックを追加する必要がある場所をすぐに見つけることができます。この方法は近道とも言えます。

それでは、 main.jsに戻りましょう。子ノードをアタッチする前に、子のタイプを決定します。そのタイプが「String」文字列の場合、 createTextNode()を使用してテキスト ノードを作成し、それを親要素にアタッチします。このようにして、文字ノードの処理が完了しました。

関数createElement(type, 属性, ...children) {
 // 要素を作成します。let element = document.createElement(type);
 // 属性をハングする for (let name in attribute) {
 要素.setAttribute(名前、属性[名前]);
 }
 // すべての子要素をハングする for (let child of children) {
 if (typeof 子 === '文字列') 
		子 = document.createTextNode(子);
 要素.appendChild(子);
 }
 //最終的に要素はノードなので、直接返すことができます return element;
}

a = <div id="a">hello world</div> とします。

ドキュメント本体に子要素を追加します。

この最新のコード webpack を使用してパッケージ化すると、テキストがブラウザーに表示されることがわかります。

この時点で、 createElementすでに便利なものであり、これを使用していくつかの DOM 操作を行うことができます。 document.createElement自分で記述するという、反復的で面倒な操作を完全に置き換えることもできます。

ここで、前の 3 つのスパンを div に再度追加し、各スパンにテキストを追加したことを確認できます。 11

a = (とする
 <div id="a">
 こんにちは世界:
 <span>あ</span>
 <span>b</span>
 <span>c</span>
 </div>
);

その後、webpack を再パックすると、この DOM 操作が実際に完了できることがわかります。

現在のコードでは、すでに特定の基本的なコンポーネント機能を実現できます。

カスタムタグの実装

以前は、HTML に付属するいくつかのタグを使用していました。 div の d を大文字の D に変更するとどうなるでしょうか?

a = (とする
 <div id="a">
 こんにちは世界:
 <span>あ</span>
 <span>b</span>
 <span>c</span>
 </Div>
); 

予想どおり、エラーが報告されます。しかし、これが問題の根本原因を見つける鍵となります。ここで、div を Div に変更すると、 createElementに渡される div が文字列 'div' からDivクラスに変更されることがわかります。

もちろん、Div クラスは JavaScript では定義されていないため、Div が定義されていないことを示すエラーが報告されます。問題がどこにあるのかがわかれば、それを解決できます。まず、未定義の問題を解決する必要があるため、まず Div クラスを作成します。

// createElment関数の後にクラスDiv {}を追加します

次に、 createElementで型判定を行う必要があります。遭遇した型が文字型である場合は、元の方法で処理します。その他の状況に遭遇した場合は、渡されたtypeをインスタンス化します。

関数createElement(type, 属性, ...children) {
 // 要素を作成する let element;
 if (typeof type === 'string') {
 要素 = document.createElement(タイプ);
 } それ以外 {
 要素 = 新しいタイプ();
 }

 // 属性をハングする for (let name in attribute) {
 要素.setAttribute(名前、属性[名前]);
 }
 // すべての子要素をハングする for (let child of children) {
 子の type が 'string' の場合、子 = document.createTextNode(child);
 要素.appendChild(子);
 }
 //最終的に要素はノードなので、直接返すことができます return element;
}

ここで別の質問があります。カスタム タグを通常の HTML タグのように動作させる方法はあるでしょうか? DOM 標準の最新バージョンでは、これを行う方法があります。カスタム タグの名前とタイプを登録するだけです。

ただし、現在のより安全なブラウジング バージョンでは、そうすることはお勧めしません。したがって、カスタム要素を使用する場合は、インターフェースを自分で記述することをお勧めします。

まず、タグ クラスを作成する必要があります。これにより、以前の通常の HTML タグの要素と同様に、任意のタグを DOM ツリーにマウントできるようになります。

以下のメソッドが含まれます。

  • mountTo() —— 後でparentノードにマウントするための要素ノードを作成する
  • setAttribute() - 要素にすべての属性を付与する
  • appendChild() - すべての子要素を要素に追加します

まず、 DivクラスにmountToメソッドを実装します。createElement に属性サブ要素をマウントするためのロジックがあるため、 setAttributeappendChildメソッドも追加する必要createElementあります。これら 2 つのメソッドが利用できない場合は、エラーが報告されます。ただし、現時点では、これら 2 つのメソッドのロジックは実装せず、メソッドの内容を空白のままにします。

クラス Div {
 属性を設定する() {}
 子要素を追加します。
 マウント先(親) {
 this.root = document.createElement('div');
 親.appendChild(this.root);
 }
}

これは実際には非常に簡単です。まず、クラスのroot属性の div 要素ノードを作成し、次にこのノードをこの要素の親にマウントします。このparentパラメータとして渡されます。

次に、元の body.appendChild コードを変更して、 mountToメソッドを使用してカスタム要素クラスをマウントします。

// document.body.appendChild(a);
ドキュメントの本文にマウントします。

現在のコードを webpack でパッケージ化して効果を確認します。

Div カスタム要素が body に正しくマウントされていることがわかります。しかし、Div 内の span タグはマウントされていません。通常の div のように動作させたい場合は、 setAttributeappendChildロジックを実装する必要があります。

次に、残りの実装ロジックを完成させてみましょう。 setAttribute と appendChild の記述を開始する前に、Div クラスにconstructorを追加する必要があります。ここで要素を作成し、それをrootにプロキシすることができます。

コンストラクタ() {
 this.root = document.createElement('div');
}

setAttributeメソッドは実際には非常に簡単です。this.root this.root使用して、DOM API でsetAttributeを呼び出すだけです。 appendChildについても同様です。最終的に、コードは次のようになります。

クラス Div {
 // コンストラクタ // DOMノードを作成するconstructor() {
 this.root = document.createElement('div');
 }
 // 要素の属性をマウントする setAttribute(name, attribute) {
 this.root.setAttribute(名前、属性);
 }
 // 要素の子要素をマウントする appendChild(child) {
 this.root.appendChild(子);
 }
 // 現在の要素をマウントする mountTo(parent) {
 親.appendChild(this.root);
 }
}

効果を確認するために、webpack でパッケージ化してみましょう。

div と span の両方が body に正常にマウントされていることがわかります。また、自作の div が正常に動作することも証明されます。

ここで別の問題が発生します。最終的にa.mountTo()を呼び出しているためです。変数aがカスタム要素ではなく、通常の HTML 要素である場合、この時点ではmountToメソッドはありません。

したがって、ここでは、通常の要素に Wrapper クラスを追加して、要素クラスの標準形式を維持できるようにする必要があります。標準インターフェースとも呼ばれます。

まずElementWrapperクラスを記述します。このクラスの内容は、実際には Div と基本的に同じです。違いは2つだけ

DOM ノードを作成するときに、現在の要素名のtypeコンストラクターに渡し、このタイプを使用して DOM ノードを作成できます。AppendChild は、通常のタグがすべてカスタム クラスに変更されるため、 this.root.appendChildを直接使用することはできません。そのため、appendChild のロジックをchild.mountTo(this.root)変更する必要があります。

クラスElementWrapper {
 // コンストラクタ // DOMノードを作成するconstructor(type) {
 要素を作成します。
 }
 // 要素の属性をマウントする setAttribute(name, attribute) {
 this.root.setAttribute(名前、属性);
 }
 // 要素の子要素をマウントする appendChild(child) {
 子をマウントします(this.root);
 }
 // 現在の要素をマウントする mountTo(parent) {
 親.appendChild(this.root);
 }
}

クラス Div {
 // コンストラクタ // DOMノードを作成するconstructor() {
 this.root = document.createElement('div');
 }
 // 要素の属性をマウントする setAttribute(name, attribute) {
 this.root.setAttribute(名前、属性);
 }
 // 要素の子要素をマウントする appendChild(child) {
 子をマウントします(this.root);
 }
 // 現在の要素をマウントする mountTo(parent) {
 親.appendChild(this.root);
 }
}

ここでまだ問題が残っています。つまり、テキスト ノードに遭遇しても、それがカスタム クラスに変換されないのです。したがって、 TextWrapperと呼ばれるテキスト ノード用のものも記述する必要があります。

クラス TextWrapper {
 // コンストラクタ // DOMノードを作成するconstructor(content) {
 ルートディレクトリに document.createTextNode(content);
 }
 // 要素の属性をマウントする setAttribute(name, attribute) {
 this.root.setAttribute(名前、属性);
 }
 // 要素の子要素をマウントする appendChild(child) {
 子をマウントします(this.root);
 }
 // 現在の要素をマウントする mountTo(parent) {
 親.appendChild(this.root);
 }
}

これらの要素クラス インターフェースを使用すると、 createElement内のロジックを書き換えることができます。元のdocument.createElementdocument.createTextNodenew ElementWrapper(type)new TextWrapper(content)インスタンス化して置き換えるだけです。

関数createElement(type, 属性, ...children) {
 // 要素を作成する let element;
 if (typeof type === 'string') {
 要素 = 新しい ElementWrapper(type);
 } それ以外 {
 要素 = 新しいタイプ();
 }

 // 属性をハングする for (let name in attribute) {
 要素.setAttribute(名前、属性[名前]);
 }
 // すべての子要素をハングする for (let child of children) {
 if (typeof 子 === '文字列') 
		子 = 新しい TextWrapper(子);
 要素.appendChild(子);
 }
 //最終的に要素はノードなので、直接返すことができます return element;
}

次に、webpack でパッケージ化して確認します。

驚くことではないが、私たちの要素全体は、通常通りボディに取り付けられている。同様に、Div を div に戻しても、正常に動作します。

もちろん、通常は意味のない Div 要素は記述しません。ここでは、カルーセルのコンポーネントであるCarouselなど、コンポーネントの名前を記述します。

完全なコード - これが役に立った場合は ⭐️ をお願いします。ありがとうございます!

JSX を使用したマークアップ コンポーネント スタイルの開発例 (フロントエンド コンポーネント化) の作成に関するこの記事はこれで終了です。関連する JSX スクリプト、JSX グループ コンポーネントの作成、JSX スタイルのコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue で jsx 構文を使用する方法
  • Vueコンポーネントjsx構文の具体的な使用
  • Vue jsx の使用ガイドと vue.js での jsx 構文の使用方法
  • jsx を使用して vue コンポーネントを記述する方法の詳細な説明

<<:  Hadoopカウンターとデータクリーニングの適用

>>:  MySQL での数値のフォーマットの詳細な説明

推薦する

MySQLオンラインログライブラリの移行例

最近の事例をお話ししましょう。オンライン Alibaba Cloud RDS 上のゲーム ログ ライ...

HTMLのタグと要素の違いの詳細な説明

ウェブページに慣れていない友人の多くは私と同じように、HTML で要素、タグ、属性がどのように定義さ...

Web フロントエンドのパフォーマンス最適化の詳細説明: リソースのマージと圧縮

2つの目的のためのリソースの結合と圧縮httpリクエストの数を減らす要求されたリソースのサイズを縮小...

複雑なSQLクエリを含むMySQLの一般的なSQL文の概要

1. 複雑なSQLクエリ1.1. 単一テーブルクエリ(1)指定の列を選択する[例] 全生徒の生徒ID...

MYSQLが中国語を認識できない問題の恒久的な解決策

ほとんどの場合、MySQL はインストールしたばかりのときは中国語をサポートしません。これはエンコー...

Nginxにモジュールを動的に追加する方法

前面に書かれた多くの場合、現在のプロジェクトの状況とビジネスニーズに基づいて Nginx をインスト...

ウェブフォームデザインのための5つの実用的なヒント

1. フォームテキスト入力のモバイル選択: テキスト入力フィールドにプロンプ​​トが追加されている場...

CSSで特殊なグラフィックを描く方法

1. 三角形境界線の設定 コード: 幅: 300ピクセル; 高さ: 300px; 背景: 赤; 境界...

1つのコマンドで、シェルの読み取りコマンドの共通パラメータを理解できます。

Shell で受信パラメータを受信する方法は 2 つあることがわかっています。 1 つはスクリプト...

スクロールバーを非表示にしてコンテンツをスクロールする CSS サンプルコード

序文ページの HTML 構造にネストされたボックスが多数含まれている場合、ページに複数の垂直スクロー...

CSSとJSでロマンチックな流星群アニメーションを実現

1. レンダリング 2. ソースコードhtml < 本文 > < div クラス ...

JavaScriptのvar let constの違いは何ですか?

目次1. 繰り返し宣言1.1 変数1.2 しましょう1.3 定数2. 可変プロモーション2.1 変数...

MySQL カウントを向上させる方法のまとめ

多くのプログラマーは MySQL に精通していると思います。多くの人が count の使い方と、最適...

ウェブページの右側に固定されたフローティングレイヤーの実装コード

コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBLIC "...

MySQL のマスター スレーブ レプリケーション オプションをオンラインで変更する方法

序文: MySQL で最も一般的に使用されるアーキテクチャは、マスター スレーブ レプリケーションで...