Vue コンポーネントはどのように解析され、レンダリングされるのでしょうか?

Vue コンポーネントはどのように解析され、レンダリングされるのでしょうか?

序文

この記事では、Vue コンポーネントがどのように解析され、レンダリングされるかを説明します。

Vue.componentを通じてグローバルコンポーネントを登録し、テンプレートで使用することができます。

<div id="アプリ">
  <私のボタン></私のボタン>
</div>
<スクリプト>
 Vue.component("my-button", {
    テンプレート: "<button> ボタンコンポーネント</button>",
   });
vm = new Vue({
	el:'#app'
});
</スクリプト>

グローバルコンポーネント解析の原則

コンポーネントの分離を保証するために、各コンポーネントは extend メソッドを通じて新しいクラスを生成し、親クラスを継承します。そして、ユーザーが Vue.component メソッドを通じて渡した opts を vue.options.components にマージし、vue が初期化されるときに Vue.options.components と vm.$options.components をマージします。

1. Vue.component メソッド

Vue.options._base = Vue; //\_baseからvueを見つけることができます
Vue.options.components を次のように記述します。 

Vue.component = 関数 (id, 定義) {
  //各コンポーネントは、親を継承する新しいクラスを生成します。definition = this.options._base.extend(definition);

  console.log("1. Vue に基づいてコンポーネントのコンストラクターを作成する", definition);

  this.options.components[id] = 定義;
 };

2. Vue.extend メソッド

extend メソッドは、Vue から継承し、親クラスのすべての機能を持つクラスを生成します。

'../util/index' から {mergeOptions} をインポートします
Vue.extend = 関数 (定義) {
  Vue.js は、次のコードで定義されます。
  const Sub = 関数 VueComponent(オプション) {
   this._init(オプション);
  };
  Sub.prototype = Object.create(Vue.prototype);
  Sub.prototype.constructor = Sub;
  Sub.options = mergeOptions(Vue.options, 定義); 
  Sub を返します。
 };

3. 属性の結合

Vue.options と Vue.component(definition) によって渡された定義をマージします。

strats.components = 関数 (親値、子値) {
 オプションを Object.create(parentVal); に設定します。
 if (childVal) {
  for (let key in childVal) {
   オプション[キー] = childVal[キー];
  }
 }
 戻りオプション。
};

4. マージを初期化する

Vue.options.components と vm.$options.components をマージする

 Vue.prototype._init = 関数 (オプション) {
  定数 vm = this;
 ++ vm.$options = mergeOptions(vm.constructor.options, オプション); 
  //...
  初期化状態(vm);
  (vm.$options.el)の場合{
   //このテンプレートにデータをマウントします vm.$mount(vm.$options.el);
  }
 };

さて、ここではグローバル コンポーネントの解析を実装しました。

次に、Kang Kang コンポーネントがどのようにレンダリングされるかを見てみましょう。

コンポーネントレンダリングの原則

仮想ノードを作成するときは、isReservedTag を使用して、現在のタグがコンポーネントであるかどうかを判断する必要があります。共通タグの仮想ノードは、コンポーネントの仮想ノードとは異なります。タグがコンポーネントである場合は、コンポーネント vnode をレンダリングする必要があります。

エクスポート関数isReservedTag(str) {
 reservedTag = "a,div,span,p,img,button,ul,li" とします。
 reservedTag.includes(str) を返します。
}

1. コンポーネント仮想ノードを作成する

createComponentはコンポーネントの仮想ノードを作成し、データにフックがあるかどうかでコンポーネントかどうかを区別します。

エクスポート関数 createElement(vm, タグ, データ = {}, ...children) {
  // タグがコンポーネントの場合、コンポーネントのvnodeをレンダリングする必要があります
  if (isReservedTag(タグ)) {
    vnode(vm, tag, data, data.key, children, undefined) を返します。
  } それ以外 {
    const Ctor = vm.$options.components[タグ]
    createComponent(vm、タグ、データ、データキー、子、Ctor) を返します。
  }
}
// コンポーネントと要素を区別するために、コンポーネントの仮想ノードを作成します。data.hook 
関数createComponent(vm, タグ, データ, キー, 子, Ctor) {
  // コンポーネントコンストラクタ if (isObject (Ctor)) {
    Ctor = vm.$options._base.extend(Ctor); // Vue.extend 
  }
  data.hook = { // この初期化メソッドはコンポーネントをレンダリングするときに呼び出す必要があります init(vnode){
      let vm = vnode.componentInstance = new Ctor({_isComponent:true}); // 新しい Sub はこのオプションとコンポーネント構成を使用してマージします vm.$mount(); // コンポーネントがマウントされると、vnode.componentInstance.$el に格納されます 
    }
  }
  vnode(vm,`vue-component-${tag}`,data,key,undefined,undefined,{Ctor,children}) を返します
}

2. コンポーネントの実際のノードを作成する

typeof tag === "string" の場合、コンポーネントの仮想ノードである可能性があり、createComponent が呼び出されます。

エクスポート関数 patch(oldVnode,vnode){
  // 1. 更新するかレンダリングするかを決定する if(!oldVnode){
    createElm(vnode) を返します。
  }それ以外{
    // ...
  }
}

関数createElm(vnode) {
 {タグ、データ、子、テキスト、vm} = vnodeとします。
 if (typeof タグ === "文字列") {
  コンポーネントを作成する場合(vnode) {
   // コンポーネントに対応する実際のノードを返します return vnode.componentInstance.$el;
  }
  vnode.el = document.createElement(tag); // 仮想ノードには、実際のノードに対応するel属性が設定されます children.forEach((child) => {
   vnode.el.appendChild(Elm(child) を作成します);
  });
 } それ以外 {
  vnode.el = document.createTextNode(テキスト);
 }
 vnode.el を返します。
}

createComponentは、データにhook.initメソッドがあるかどうかによって、コンポーネントが仮想ノードであるかどうかを判断します。

はいの場合は、コンポーネントでdata.hook.initを呼び出します。

コンポーネントインスタンスを作成し、vnode.componentInstanceに割り当てます。

vnode.componentInstance に値がある場合、対応するコンポーネントの実際の DOM が生成されたことを意味します。

関数createComponent(vnode) {
  i = vnode.data とします。
  if((i = i.hook) && (i = i.init)){
    i(vnode);
  }
  if(vnode.componentInstance){
    true を返します。
  }
}

initメソッドを呼び出してコンポーネントのインスタンスを作成し、マウントします。

データ.フック = {
  init(vnode){
    子を vnode.componentInstance に新しい Ctor({}) として追加します。
    child.$mount(); // コンポーネントのマウント}
}

まとめ

新しいコンポーネント (). $mount () => vm. $el

コンポーネントの$elを親コンテナ(親コンポーネント)に挿入します。

完了しました!

上記は、Vue コンポーネントがどのように解析され、レンダリングされるかを示しています。 Vue コンポーネントの解析とレンダリングの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vue の動的コンポーネントと非同期コンポーネントの詳細な理解
  • Vue が Ref を使用してレベル間でコンポーネントを取得する手順
  • Vueはマルチタブコンポーネントを実装します
  • Vue再帰コンポーネントの簡単な使用例
  • Vueはキー表示のショートカットキー効果を取得する入力コンポーネントを実装します
  • Vue の親コンポーネントと子コンポーネント間の通信の例 (props、$ref、$emit)
  • Vue マウントコンポーネントの使用
  • Vue は他のコンポーネント (css と js) をどのように参照しますか
  • vue-dialog のポップアップ レイヤー コンポーネント
  • Vueコンポーネントの基本のまとめ

<<:  Vueはキー表示のショートカットキー効果を取得する入力コンポーネントを実装します

>>:  ランダムな文字を生成する Java サンプルコード

推薦する

JQuery データグリッドクエリの詳細な説明

目次ツリー項目にコードを追加します。 1. 右側に関連情報ページを保存します(userManage....

ウェブページでコンテンツを引用するためによく使われるHTMLタグをマスターする

長い引用には blockquote を、短い引用には q を、参考文献には cite を使用します。...

Dockerコンテナを停止または強制終了できない問題の解決策

Docker バージョン 1.13.1問題プロセス特定の環境のMySQLコンテナを停止、強制終了、ま...

Vue カードスタイルのクリックして切り替える画像コンポーネントの使用方法の詳細な説明

この記事では、vueカードスタイルのクリックして切り替える画像コンポーネントを参考までに紹介します。...

CSS3は、欠けた角の長方形、折り畳まれた角の長方形、欠けた角の境界線を実装しています。

序文数日前、偶然、コーナーの四角形が欠落している機能に遭遇しました。最初に頭に浮かんだのは、必要な場...

js で継承を実装する 5 つの方法

コンストラクタの借用この手法の基本的な考え方は単純です。サブタイプ コンストラクター内からスーパータ...

JavaScriptのループの違いについての詳細な説明

目次序文列挙可能なプロパティ反復可能なオブジェクトforEachメソッドとmapメソッドチェーン呼び...

CentOS8でのnmcliの使い方の詳しい説明

RHEL8/CentOS8 に基づく一般的な nmcli コマンド # IP を表示する (ifco...

MySQL の遅いクエリを見つける方法

序文誰もが日常業務で SQL の最適化を経験したことがあると思います。したがって、最適化の前に、遅い...

イメージの起動時にdocker runまたはdocker restartが自動的に終了する問題を解決します

コマンドを実行します: docker run --name centos8 -d centos /b...

Docker で lnmp をデプロイする詳細な手順

目次Centosイメージを取得するCentos ベースの nginx コンテナを生成するCentos...

MySQL ストレージ エンジン MyISAM と InnoDB の違いの概要

1. MySQLのデフォルトストレージエンジンの変更MySQL 5.1 より前のバージョンでは、デフ...

Docker で複数のアプリケーション サイトをプロキシするために Nginx を使用する方法

序文エージェントの役割は何ですか? - 複数のドメイン名が同じサーバーに解決される- 1つのサーバー...

史上最もシンプルな MySQL データのバックアップと復元のチュートリアル (パート 1) (パート 35)

データのバックアップと復元に関する最初の記事を皆さんに共有します。具体的な内容は次のとおりです。基本...

Linux lnコマンドの使用

1. コマンドの紹介ln コマンドは、ファイルのリンクを作成するために使用されます。リンクは、ハード...