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クエリの基本的なクエリ操作の学習

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

推薦する

JavaScript ESの新機能letとconstキーワードに基づく

目次1. letキーワード1.1 基本的な使い方1.2 変動昇進はない1.3 一時的なデッドゾーン1...

Mysql | ワイルドカード(%、_ など)を使用したファジークエリの詳細な説明

ワイルドカードのカテゴリ: %パーセント ワイルドカード: 任意の文字が任意の回数出現できることを示...

Dockerを使用してSpringBootプロジェクトをデプロイする方法

Docker テクノロジの開発により、マイクロサービスの実装にさらに便利な環境が提供されます。Doc...

Nginx リバース プロキシと負荷分散を実装する方法 (Linux ベース)

ここで nginx のリバース プロキシを試してみましょう。リバースプロキシ方式とは、インターネット...

要素の読み込み効果を実現するための純粋なHTML+CSS

これは Element UI の読み込みコンポーネントのエフェクトです。かっこいいですね。実装してみ...

CSS3で実装された水平ヘッダーメニュー

結果:実装コードhtml <nav class="dropdownmenu"...

DockerでJenkinsをインストールし、初期プラグインのインストール失敗の問題を解決する

Jenkins をインストールした後、プラグインの初期ダウンロードが常に失敗し、インストールが失敗し...

MySQLデータベースのbinlogクリーンアップコマンドの詳細な説明

概要今日は主に、MySQL データベースから binlog ログを正しく削除する方法を紹介します。ロ...

CSSを使用して中央に固定された2つの列と適応型列を実現する方法

1. 絶対位置とマージンを使用するこの方法の原則は、左側と右側をドキュメントの流れから外れるように配...

JavaScript の遅延読み込み属性パターンを理解する

従来、開発者はインスタンスで必要になる可能性のあるデータに対して JavaScript クラス内にプ...

MySQLシリーズのMariaDBサーバーのインストール

目次チュートリアルシリーズ1. yumパッケージマネージャーを使用してMariaDBサーバーをインス...

入力選択スタイルを変更する CSS 疑似クラスのサンプルコード

注: この表はW3Schoolチュートリアルから引用したものです疑似要素の分類と機能: 入力選択スタ...

Ubuntu 18.04 に VMware Tools をインストールする際のエラーを解決する

1. オンライン チュートリアルによると、Ubuntu 18.04 のインストールはまだ失敗します。...

MYSQL の binlog 最適化に関する考察の要約

質問質問 1: トランザクションをコミットするときに REDO ログをフラッシュすることによって発生...

SpringBoot プロジェクトの Docker 環境を実行するときに発生する無限再起動問題の詳細な説明

もしかしたら私の考え方が間違っていたのかもしれないし、問題の説明が少し乱雑だったのかもしれないが、こ...