Vue で jsx 構文を正しく使用する方法

Vue で jsx 構文を正しく使用する方法

序文

また怠ける時間です。無駄にはできないと思います。H5 ページに vant を使っています。ソース コードに興味があったので、git から vant ソース コードのコピーを取得しました。すべてのコンポーネントが jsx で記述されていることが判明したので、vue で jsx を使用する方法を調べ始めました。

仮想DOM

仮想DOMとは

その前に、まずは仮想 DOM について理解しましょう。Vue と React フレームワークはどちらも内部的に仮想 DOM を使用しています。その理由は、JS を通じて DOM を操作する計算コストが非常に高いためです。JS は非常に高速に更新されますが、DOM を見つけて更新するコストは非常に高くなります。では、どのような方法で最適化できるでしょうか? Vue などのフレームワークは js オブジェクトを使用します。js オブジェクトは変更され、バッチ処理されて DOM を一度に更新します。したがって、仮想 DOM は本質的に js オブジェクトです。

仮想DOMの利点

  • 実DOMの本来の操作から仮想DOMの操作に移行し、検索コストを削減
  • 差分比較により、データの変更をより迅速に特定し、DOMを更新することができます。
  • より良いUIアップデート
  • 抽象レンダリングプロセス、vue3 の createRenderer API などのクロスプラットフォーム機能を実現

レンダリング関数とは何ですか?

レンダリング関数は仮想 DOM を生成するために使用されます。テンプレート構文を単一のvueファイルに記述し、最終的には基礎となる実装のレンダリング関数にコンパイルされます。

Vue では、ほとんどの場合、テンプレートを使用して HTML を作成することを推奨しています。ただし、シナリオによっては、JavaScript の完全なプログラミング能力が本当に必要になる場合があります。この場合、テンプレートよりもコンパイラに近いレンダリング関数を使用できます。

次のようなシナリオが発生した場合、次の書き方で目的の効果を達成できますが、長くなるだけでなく、レベルタイトルごとに繰り返すことになります。アンカー要素を追加すると、各v-if/v-else-ifブランチでそれを再度繰り返す必要があります。

const {createApp} = Vue

const アプリ = createApp({})

app.component('アンカー付き見出し', {
  テンプレート: `
    <h1 v-if="レベル === 1">
      <スロット></スロット>
    </h1>
    <h2 v-else-if="レベル === 2">
      <スロット></スロット>
    </h2>
    <h3 v-else-if="レベル === 3">
      <スロット></スロット>
    </h3>
    <h4 v-else-if="レベル === 4">
      <スロット></スロット>
    </h4>
    <h5 v-else-if="レベル === 5">
      <スロット></スロット>
    </h5>
    <h6 v-else-if="レベル === 6">
      <スロット></スロット>
    </h6>
  `、
  小道具: {
    レベル:
      タイプ: 数値、
      必須: true
    }
  }
})

テンプレートはほとんどのコンポーネントでうまく機能しますが、ここでは明らかに適切ではありません。それでは、render 関数を使用して上記の例を書き直してみましょう。

const { createApp, h } = Vue

const アプリ = createApp({})

app.component('アンカー付き見出し', {
  与える() {
    h(を返す
      'h' + this.level, // タグ名
      {}, // プロパティ/属性
      this.$slots.default() // 子の配列
    )
  },
  小道具: {
    レベル:
      タイプ: 数値、
      必須: true
    }
  }
})

jsx

このようにレンダリング関数を書くのは少し面倒です。テンプレートに近い形で書く方法はありますか?Vueは、Vueがjsxの記述をサポートするようにするためのbabel-plugin-jsx babelプラグインを提供しています。

私は vuecli を使用して vue3 + ts プロジェクトを作成します。スキャフォールディングでは、jsx と ts の関連する依存関係が統合されています。

Vue3 で JSX を書く 2 つの方法

ファイルのサフィックスをvueからtsxまたはjsxに直接変更する

vue3では、レンダリングオプションを直接使用して次のように記述できます。

「vue」からdefineComponentをインポートします。
エクスポートデフォルトdefineComponent({
  名前: "Jsx",
  与える() {
    <div>私はdivです</div>を返します。
  },
});

セットアップで戻ることもできます

「vue」からdefineComponentをインポートします。
エクスポートデフォルトdefineComponent({
  名前: "Jsx",
  設定() {
    return () => <div>私はdivです</div>;
  },
});

どちらの方法も、個人の好みに応じて受け入れ可能です。setup ではこれにアクセスできませんが、render ではこれを介して現在の Vue インスタンスにアクセスできます。

使用法

クラス バインディングは react の jsx バインディングとは異なります。React は className を使用し、vue は class を使用します。

 設定() {
   return () => <div class="test">私はdivです</div>;
 },

スタイルバインディング

  設定() {
    return () => <div style={{ color: "red" }}>私はdivです</div>;
  },

プロップバインディング

// 親コンポーネントのセットアップ() {
    戻り値 () => (
      <div style={{ color: "赤" }}>
        <span>私は親コンポーネントです</span>
        <Mycom msg={"私は親コンポーネントから渡された値です"} />
      </div>
 );
// サブコンポーネント、setupの最初のパラメータはpropsで値を取得できます setup(props) {
    return () => <div>私は子コンポーネントです {props.msg}</div>;
  },

イベントバインディング

設定() {
    関数eventClick() {
      console.log("クリック");
    }
    return () => <button onClick={eventClick}>ボタン</button>;
},

コンポーネントのカスタムイベント

// サブコンポーネント import { defineComponent } from "vue";
エクスポートデフォルトdefineComponent({
  名前:「マイコム」
  発行: ["イベント"],
  セットアップ(props, { 出力 }) {
    関数sendData() {
      emitting("event", "サブコンポーネントによって渡されたデータ");
    }
    戻り値 () => (
      <div>
        <span>カスタム イベント</span>
        <button onClick={sendData}>データを送信</button>
      </div>
    );
  },
});
// 親コンポーネント // @ts-nocheck
// これは jsx では問題ありませんが、tsx では ts 型エラーが報告されるため、上記の現在のファイル ts 監視 @ts-nocheck を無視しました。
「vue」からdefineComponentをインポートします。
Mycomを「./mycom」からインポートします。
エクスポートデフォルトdefineComponent({
  名前: "Jsx",
  設定() {
    関数 getSon(msg: 文字列) {
      コンソールログ(メッセージ);
    }
    戻り値 () => (
      <div>
        <Mycom onEvent={getSon} />
      </div>
    );
  },
});

ts型エラーもこの方法で解決できます

  設定() {
    関数 getSon(msg: 文字列) {
      コンソールログ(メッセージ);
    }
    戻り値 () => (
      <div>
        <Mycom {...{ onEvent: getSon }} />
      </div>
    );
  },

スロット

// 親コンポーネントのセットアップ() {
    定数スロット = {
      テスト: () => <div>名前付きスロット</div>,
      デフォルト: () => <div>デフォルトスロット</div>,
    };
    戻り値 () => (
      <div>
        <Mycom v-slots={スロット}></Mycom>
      </div>
    );
},
セットアップ(props, { スロット }) {
// サブコンポーネント return () => (
      <div>
        <span>スロット</span>
        {スロット.default?.()}
        {スロット.テスト?.()}
      </div>
    );
  },

v-if、v-for などの命令は jsx では使用できません。jsx は v-model および v-show 命令のみをサポートしています。

  設定() {
    const inputData = ref("");
    戻り値 () => (
      <div>
        <span v-show={true}>表示</span>
        <span v-show={false}>非表示</span>
        <input type="text" v-model={inputData.value} />
        <span>{入力データ値}</span>
      </div>
    );
},

やっと

さっそく、vantのソースコードを開いて、src => button => button.tsxを読んで最初のコンポーネントのソースコードを開く準備をします。

これで、vue での jsx の正しい使用に関するこの記事は終了です。vue での jsx の使用に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

参照する

    vue レンダリング関数
  • vuejsx ドキュメント
  • 問題
以下もご興味があるかもしれません:
  • Vue3 のレンダリング関数における互換性のない変更の詳細な説明
  • Vueレンダリング関数renderの使い方の詳しい説明
  • Vueレンダリング機能の詳しい説明
  • React-vscode で jsx 構文を使用する際の問題と解決策
  • JSX を使用してコンポーネント パーサー開発を構築する例
  • JSX を使用してカルーセル コンポーネントを実装する方法 (フロントエンドのコンポーネント化)
  • Vueコンポーネントjsx構文の具体的な使用
  • Vue jsx の使用ガイドと vue.js での jsx 構文の使用方法
  • Vue が JSX 構文をサポートする方法の詳細な説明
  • レンダリング関数と JSX の詳細

<<:  VMware仮想マシンにLinux(CentOS)をインストールするための詳細な構成手順

>>:  Windows に MySQL をインストールする方法のグラフィック チュートリアル

推薦する

Nginx 最適化サービスで Web ページ圧縮を実装する方法

リソースを節約するためにWebページの圧縮を設定する1.まず、設定を変更しましょう vim /usr...

nginx設定ファイルの解釈の詳細な説明

nginx 設定ファイルは主に 4 つの部分に分かれています。 main{#(グローバル設定) ht...

Alibaba Cloud Nginx はドメイン名アクセス プロジェクトを実装するために https を設定します (グラフィック チュートリアル)

ステップ1: サードパーティの信頼できるSSL証明書に署名するAlibaba Cloud で直接、無...

Unicode署名BOMによる事故原因の分析

ここでは、通常ヘッダーとフッターに対して行われるインクルード ファイルを使用している可能性があります...

React 手書きタブ切り替え問題

親ファイル React をインポートし、{useState} を 'react' か...

MySQLレジストリをクリアする方法

具体的な方法: 1. [ win+r ] を押して実行ウィンドウを開き、「regedit」と入力して...

DockerにrockerChatをインストールし、チャットルームを設定するための詳細な手順

包括的なドキュメントgithubアドレスhttps://github.com/RocketChat/...

<td></td> タグの境界線スタイルがブラウザに表示されない問題の解決方法

質問: 360ブラウザの互換モードなど、一部のブラウザでは、 <td style="...

MySQLは1億のテストデータを素早く挿入します

目次1. テーブルを作成する1.1 テストテーブルt_userを作成する1.2 一時テーブルの作成2...

MySQL DISTINCTの基本実装原理の詳細な説明

序文DISTINCT は、GROUP BY 操作の実装と非常によく似ていますが、GROUP BY の...

Windows での MySQL スケジュールバックアップ スクリプトの実装

Windows サーバーでデータベース データを定期的にバックアップする場合は、Windows タス...

iviewは動的なフォームとカスタム検証期間の重複を実装します

フォーム項目を動的に追加するiview の動的なフォーム追加は非常に簡単です。フォーム項目を配列に設...

仮想マシンのディスクサイズを拡張する方法

Vmvare が仮想マシンのディスク サイズを設定した後、ディスク領域が不足していることがわかりまし...

Docker nginxは1つのホストを実装して複数のサイトを展開します

とあるサイトからレンタルした仮想マシンの有効期限が近づいており、更新料が200元以上かかります。Al...