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 をインストールする方法のグラフィック チュートリアル

推薦する

Dockerイメージが消える問題を解決する

1. 50と93では鏡像が消える [root@h50 /]# df -h ファイルシステムの使用済み...

Docker を使用してフロントエンド アプリケーションをデプロイする方法

Dockerはますます普及しています。環境を軽量かつ柔軟に分離し、容量を拡張し、運用保守管理を容易に...

mysql の追加、削除、変更、クエリの基本ステートメント

文法以下は、MySQL テーブルにデータを挿入するための INSERT INTO コマンドの一般的な...

GNU Parallelの具体的な使用法

それは何ですか? GNU Parallel は、1 台以上のコンピュータでコンピューティング タスク...

Linux での SELinux を理解する方法

目次1. SELinux の紹介2. SELinuxの基本概念2.1 仕事の種類2.2. セキュリテ...

シンプルなウェブページレイアウトの構造と表現原理の共有

構造とパフォーマンスの紹介HTML 構造、CSS 表現、JavaScript 動作。Web ページの...

1つの記事でNavicat for MySQLの基本を理解する

目次1. データベース操作2. データ型3. バックアップとリカバリ3. 操作4. 上級5. 知識補...

mybatis-plusページングパラメータが渡された後、SQLのwhere条件にはページング情報操作の制限がありません

2時間近くかけて、さまざまな方法を試しました。後で、whereでフィルタリングした後のデータ量が1ペ...

Dockerコンテナの個別展開のためのLNMPの実装

1. 環境整備各コンテナの IP アドレス: nginx: 172.16.10.10マイSQL: 1...

ElementUIはel-formフォームリセット機能ボタンを実装します

目次ビジネスシナリオ:効果のデモンストレーション:ビジネスシナリオ: el-form を使用する場合...

mysql5.7.18 解凍バージョンで mysql サービスを起動します

mysql5.7.18の解凍版はmysqlサービスを起動します。具体的な内容は以下のとおりです。 1...

VMware15 の CentOS7 インストールの詳細なプロセスとよくある問題 (画像とテキスト)

1. インストールパッケージの準備VMware-player-15.0.4-12990004、非商...

MySQLのunion allとunionの違いを簡単に理解する

Union は、重複行を除外し、デフォルトのソートを実行する、データに対する結合操作です。Union...

HTML マウス CSS コントロール

一般的に、マウスは上向きの斜め矢印として表示され、テキストの上に移動すると垂直線になり、ハイパーリン...