Vue の高度なコンポーネント機能コンポーネントの使用シナリオとソースコード分析

Vue の高度なコンポーネント機能コンポーネントの使用シナリオとソースコード分析

導入

Vue は、コンポーネントをステートレスかつインスタンスフリーにできる機能コンポーネントを提供します。原則として、ほとんどのサブコンポーネントはインスタンス化のプロセスを経ますが、純粋な関数コンポーネントにはこのプロセスがありません。これは、データを処理するだけでインスタンスを作成しない中間層として簡単に理解できます。また、この動作により、レンダリングのオーバーヘッドが大幅に低くなります。実際のアプリケーション シナリオでは、複数のコンポーネントから 1 つを選択してレンダリングする必要がある場合、または子コンポーネントに渡す前に、子、プロパティ、データなどのデータを処理する必要がある場合に、機能コンポーネントを使用してこれを完了できます。これは、基本的にコンポーネントの外部パッケージ化です。

使用シナリオ

2つのコンポーネントオブジェクトtest1、test2を定義します。

var test1 = {
プロパティ: ['msg'],
レンダリング: 関数 (createElement, コンテキスト) {
  createElement('h1', this.msg) を返します。
}
}
var test2 = {
プロパティ: ['msg'],
レンダリング: 関数 (createElement, コンテキスト) {
  createElement('h2', this.msg) を返します。
}
}

計算結果に基づいて選択するコンポーネントの1つを選択する機能コンポーネントを定義する

Vue.component('test3', {
// 機能コンポーネントのフラグ functional が true に設定されている
機能的: 真、
プロパティ: ['msg'],
レンダリング: 関数 (createElement, コンテキスト) {
  var get = 関数() {
    テスト1を返す
  }
  createElement(get(), context) を返す
}
})

機能コンポーネントの使用

<test3 :msg="メッセージ" id="テスト">
</テスト3>
新しいVue({
el: '#app',
データ: {
  メッセージ: 'テスト'
}
})

最終的なレンダリング結果は次のとおりです。

<h2>テスト</h2>

ソースコード分析

機能コンポーネントは、コンポーネント オブジェクト定義で functional プロパティを true に設定します。このプロパティは、通常のコンポーネントと機能コンポーネントを区別する鍵となります。同様に、サブコンポーネント プレースホルダーに遭遇すると、createComponent が入力され、サブコンポーネント Vnode が作成されます。機能プロパティが存在するため、コードは機能コンポーネント ブランチに入り、createFunctionalComponent 呼び出しの結果を返します。 createFunctionalComponent を実行した後は、子 Vnode を作成する後続のロジックは実行されないことに注意してください。これは、実際のノードを作成するプロセスで子コンポーネントをインスタンス化する子 Vnode が存在しない理由でもあります。 (例なし)

関数createComponent(){
  ···
  if (isTrue(Ctor.options. functional)) {
    createFunctionalComponent(Ctor、propsData、データ、コンテキスト、子) を返します。
  }
}

createFunctionalComponent メソッドは、受信データを検出してマージし、FunctionalRenderContext をインスタンス化し、最後に機能コンポーネントのカスタム レンダリング メソッドを呼び出してレンダリング プロセスを実行します。

関数createFunctionalComponent()
  Ctor, // 関数コンポーネントコンストラクタ propsData, // コンポーネントに渡されるプロパティ
  data, // attr プレースホルダー コンポーネントによって渡される属性 context, // vue インスタンス children// 子ノード){
  //データの検出とマージ var options = Ctor.options;
  var プロパティ = {};
  var propOptions = オプション.props;
  if (isDef(propOptions)) {
    for (var key in propOptions) {
      props[key] = validProp(key, propOptions, propsData || emptyObject);
    }
  } それ以外 {
    //属性をマージ
    if (isDef(data.attrs)) { mergeProps(props, data.attrs); }
    // プロパティをマージする
    if (isDef(data.props)) { mergeProps(props, data.props); }
  }
  var renderContext = 新しい FunctionalRenderContext(data,props,children,contextVm,Ctor);
  // 関数コンポーネント内のカスタムレンダリング関数を呼び出す var vnode = options.render.call(null, renderContext._c, renderContext)
}

FunctionalRenderContext クラスの最終的な目的は、実際のコンポーネントのレンダリングとは異なるレンダリング メソッドを定義することです。

関数FunctionalRenderContext() {
  //他のロジックを省略 this._c = function (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); };
}

レンダリング関数の実行中に、createElement メソッドが再帰的に呼び出されます。この時点で、コンポーネントはすでに実際のコンポーネントであり、通常のコンポーネントマウントプロセスの実行を開始します。

質問: 機能コンポーネントで別の createElement メソッドを定義する必要があるのはなぜですか? - 関数コンポーネント createElement と以前のコンポーネントの唯一の違いは、最後のパラメータです。前の章で述べたように、createElement は最後のパラメータに基づいて子 Vnode をフラット化するかどうかを決定します。通常、子のコンパイル結果は Vnode 型です。関数コンポーネントだけが特別です。配列を返すことができます。この場合、フラット化が必要です。次の例を見てみましょう。

Vue.component('テスト', {  
  機能的: 真、  
  レンダリング: 関数 (createElement, コンテキスト) {  
    context.slots().default を返す  
  }  
}) 

<テスト> 
     <p>スロット1</p> 
     <p>スロット</p> 
</テスト>

このとき、機能コンポーネントテストのレンダリング関数は、配列の形式で存在する 2 つのスロットの Vnode を返します。これがフラット化する必要があるシーンです。

機能コンポーネントを簡単にまとめると、ソースコードからわかるように、機能コンポーネントには、通常のコンポーネントのようにコンポーネントをインスタンス化するプロセスがないため、コンポーネントのライフサイクルやコンポーネントのデータ管理などのプロセスはありません。コンポーネントに渡されたデータをそのまま受け取って処理し、必要なコンテンツをレンダリングするだけです。したがって、純粋な関数として、レンダリングのオーバーヘッドを大幅に削減できます。

要約する

これで、Vue の高度なコンポーネントと機能コンポーネントの使用シナリオとソースコード分析に関するこの記事は終了です。Vue の高度なコンポーネントと機能コンポーネントに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue機能コンポーネントの詳細な応用例
  • Vue 関数コンポーネント - あなたにふさわしい
  • Vue関数コンポーネントの使用に関する簡単な説明

<<:  MySQLクエリの基本的なクエリ操作の学習

>>:  良いデザインについて

推薦する

nginx でのリクエストのカウント追跡の簡単な分析

まずは適用方法を説明します。nginxモジュールにはjtxyとjtcmdの2つがあります。 http...

CSS グリッドレイアウトで列にアイテムを埋め込む方法

n 個のアイテムがあり、これらのアイテムをグリッド レイアウトの列に並べ替える必要があるとします。列...

Reactの状態の理解についての簡単な分析

複雑なコンポーネント (クラス コンポーネント) と単純なコンポーネント (関数コンポーネント) を...

MySQL無料インストールバージョンの設定チュートリアル

この記事では、参考までにMySQLの無料インストール構成チュートリアルを紹介します。具体的な内容は次...

CSS は Google マテリアル デザインのテキスト入力ボックス スタイルを実装します (推奨)

みなさんこんにちは。今日は、純粋な CSS を使用して Google マテリアル デザインのテキスト...

ローカルのMySQLをサーバーデータベースに移行する方法

Linux の scp コマンド (Windows では scp は使用できません) と、mysql...

ウェブデザインにおけるポップアップウィンドウとフローティングレイヤーのデザイン

従来のソフトウェアから Web ウェアへの段階的な移行の傾向の中で、デザイン パターンとテクノロジは...

MySQL データベースの制約とデータ テーブルの設計原則

目次1. データベースの制約1.1 はじめに1.2 制約の種類1.3 ヌルでない1.4 ユニーク1....

JavaScript のプライベート クラス フィールドと TypeScript のプライベート修飾子の詳細な説明

目次JavaScript のプライベート クラス フィールドとプライバシーの必要性JavaScrip...

JavaScript におけるイベント バブリング メカニズムの詳細な分析

バブリングとは何ですか? DOM イベント フローには、イベント キャプチャ ステージ、ターゲット ...

ラベルタグの使用時に発生する問題の分析と解決策

最近何かをするときにラベル タグを使用しました。以前はラベル タグをほとんど使用していなかったため、...

MySQLで行を列に変換する方法

MySQL の行から列への操作いわゆる行から列への操作は、テーブルの行情報を列情報に変換することです...

自動ヘルスレポートを実現するDocker+Selenium方式

この記事では、ある大学の健康報告システムを例に、Web 側の自動化操作を完成させます。使用したテクノ...

Docker で Java 8 Spring Boot アプリケーションを開発する方法

この記事では、ローカル マシンに Java 8 をインストールせずに、Java 8 を使用して簡単な...