昨日、友人から、ページが最初に読み込まれたときに Vue は何をするのかと尋ねられました。この質問は、多くの友人の心の中で漠然としているようです。今日は、Vue の最初のレンダリング プロセスを詳しく見てみましょう。 Vueの最初のレンダリングのプロセス全体を理解するには、どこから始めるべきでしょうか?明らかに、エントリファイル、つまりmain.jsから始める必要があります。 1. Vueの初期化まず、main.js を見てみましょう。最初で最も重要なことは、vue を導入することです。 'vue' から vue をインポートします 実際、vueがパッケージ化された後、distフォルダには複数のバージョンがあります。 では、vue が導入された後、vue 内の関連コードは実行されるのでしょうか? Vueソースコード内のどのコードが最も最近実行されたか(導入されたVueはVueソースコードにパッケージ化されたVueです)を知るには、まずエントリファイルがどこにあるかを知る必要があります。 vue エントリ ファイルVueのエントリファイルは主にVueソースコード構造のsrc/platforms/webの下にあります。 Vue をパッケージ化するときに、パッケージ化用に異なる Vue エントリ ファイルを選択できます。エントリ ファイルが異なると、異なる Vue バージョンがパッケージ化されます。 フルバージョンとランタイムバージョンの違いフルバージョンは、ランタイムバージョン + コンパイラの組み合わせです。ランタイムバージョンにはコンパイラがありません。つまり、テンプレートコンパイル機能はありません。主に Vue インスタンスの作成と仮想 DOM のレンダリングに使用されます。より小さく、より軽量(コンパイラのコードは 3,000 行以上) <本文> <div id="アプリ"> <p>私はindex.htmlのコンテンツです</p> </div> </本文> 新しいVue({ テンプレート: '<div>私はテンプレートによってレンダリングされたコンテンツです</div>' }).$mount('#app') 上記の状況、 ランタイムバージョンの場合、コンパイラは存在せず、テンプレート内のコンテンツはコンパイルされないため、ページには元のDOMのみが含まれる。 では、下を見てエントリファイルを探しましょう。何が実行されるかを見てみましょう。 エントリファイルは最初にvueをインポートし、その後いくつかの処理を経て、最後にvueをエクスポートしていることがわかります。 このファイルも同じです。vueをインポートし、いくつかの処理を行ってからvueをエクスポートします。core/indexを探してみましょう。 このファイルについても同じことが言えます。検索を続けて./instance/indexを見つけましょう。 ここでは、ソース コードの src/core/instance/index.js ファイルにある vue コンストラクターの作成が見つかります。 そして、上記の参照関係から、Vueをプロジェクトに導入した後、最初に実行されるファイルの順序は次のようになります。 src/core/instace/index.js ===> 1 src/core/index.js ===> 2 src/platforms/web/runtime/index.js ===> 3 src/platforms/web/entry-runtime-with-compiler.js 4 それでは、各ファイルが何を実行するか見てみましょう。 1.1、src/core/instace/index.jsまず、このファイルはvueコンストラクタを定義し、いくつかのvueインスタンスプロパティとインスタンスメソッドを初期化します。つまり、vue.prototypeプロトタイプの下にさまざまなメソッドとプロパティが追加されます。 次に、各メソッドによって Vue のどのインスタンス プロパティまたはメソッドが初期化されるかを詳しく見てみましょう。 1.1.1、initMixin(Vue) 1.1.2、stateMixin(Vue) 1.1.3、イベントMixin(Vue) 1.1.4、ライフサイクルミックスイン(Vue) 1.1.5、レンダリングミックスイン(Vue) src/core/instace/index.jsが実行された後、次のファイルの実行が続行されます。 エクスポート関数 initGlobalAPI (Vue: GlobalAPI) { // 設定 定数configDef = {} configDef.get = () => 設定 process.env.NODE_ENV !== 'production' の場合 { configDef.set = () => { 警告( 「Vue.config オブジェクトを置き換えないで、代わりに個々のフィールドを設定してください。」 ) } } // 新しい設定プロパティを追加しました Object.defineProperty(Vue, 'config', configDef) // 新しい静的メンバー util を追加しました Vue.util = { 警告する、 伸ばす、 マージオプション、 定義Reactive } // 3 つの静的メンバーを追加 set delete nextTick Vue.set = 設定 Vue.delete = del Vue.nextTick = 次のティック // 新しい静的メンバー observable を追加しました Vue.observable = <T>(obj: T): T => { 観察する(obj) オブジェクトを返す } // オプションを初期化します。オプションは空のオブジェクトです。</T> Vue.options = Object.create(null) ASSET_TYPES.forEach(タイプ => { Vue.options[type + 's'] = Object.create(null) }) Vue.options._base = Vue // グローバル コンポーネント keep-alive を登録します。builtInComponents 内には keep-alive コンポーネントがあります。export extend(Vue.options.components,builtInComponents) // 以下は初期化されます Vue.use() Vue.mixin() Vue.extend() initUse(Vue) initMixin(Vue) initExtend(Vue) // Vue.directive()、Vue.component()、vue.filter() を初期化します アセットレジスタの初期化(Vue) } 1.2、src/core/index.jsこのファイルは主に、Vue に多くの静的インスタンス メソッドとプロパティを追加していることがわかります。具体的には何が追加されるのでしょうか? 1.2.1 initGlobalAPI(Vue) エクスポート関数 initGlobalAPI (Vue: GlobalAPI) { // 設定 定数configDef = {} configDef.get = () => 設定 process.env.NODE_ENV !== 'production' の場合 { configDef.set = () => { 警告( 「Vue.config オブジェクトを置き換えないで、代わりに個々のフィールドを設定してください。」 ) } } // 新しい設定プロパティを追加しました Object.defineProperty(Vue, 'config', configDef) // 新しい静的メンバー util を追加しました Vue.util = { 警告する、 伸ばす、 マージオプション、 定義Reactive } // 3 つの静的メンバーを追加 set delete nextTick Vue.set = 設定 Vue.delete = del Vue.nextTick = 次のティック // 新しい静的メンバー observable を追加しました Vue.observable = <T>(obj: T): T => { 観察する(obj) オブジェクトを返す } // オプションを初期化します。オプションは空のオブジェクトです。</T> Vue.options = Object.create(null) ASSET_TYPES.forEach(タイプ => { Vue.options[type + 's'] = Object.create(null) }) Vue.options._base = Vue // グローバル コンポーネント keep-alive を登録します。builtInComponents 内には keep-alive コンポーネントがあります。export extend(Vue.options.components,builtInComponents) // 以下は初期化されます Vue.use() Vue.mixin() Vue.extend() initUse(Vue) initMixin(Vue) initExtend(Vue) // Vue.directive()、Vue.component()、vue.filter() を初期化します アセットレジスタの初期化(Vue) } 1.3、src/platforms/web/runtime/index.js1.4、src/platforms/web/entry-runtime-with-compiler.jsこのファイルの主な機能は、vue プロトタイプの下の $mount メソッドを書き換えることです。 $mount メソッドで何が行われるかについては後ほど説明します。 1.5. Vue初期化の概要上記のプロセス全体は、ユーザーがvueを使用するときにvueファイルをインポートした直後に実行されるものです。 これらが実行された後、プロジェクト内の main.js ファイルの実行が継続されますか? 新しいVue({ ルーター、 店、 レンダリング: h => h(App) }).$mount('#app') この時点で、vueコンストラクタが呼び出され始めます。 2. Vueコンストラクタの実行この時点で、vue コンストラクターが最初に実行されます。 _initメソッドが主に実行されていることがわかります。ここからVueのライフサイクルが実行され始めます。 上記は、_init() メソッドのコードの中で最も重要な部分です (コードが多すぎるため、すべてのスクリーンショットは撮りません。ソース コードを自分で確認できます)。次のことがわかります。 2.1. beforeCreateフックライフサイクルの beforeCreate フックの前に、vue が行う主なことは、vue プロトタイプにさまざまなプロパティとメソッドを追加し、vue にさまざまな静的プロパティとメソッドを追加し、vm インスタンスにさまざまなプロパティとメソッドを追加することです。 2.2、フック作成上の図からわかるように、beforeCreateフックが実行された後、主にinitInjections、initState、initProvideの3つのメソッドが実行されます。 // VMインスタンスに注入する callHook(vm, 'beforeCreate') // VMインスタンスに注入する initInjections(vm) // VM の $props、$methods、$data、computed、watch を初期化します 初期化状態(vm) // provide を vm インスタンスに注入する initProvide(vm) //作成されたライフサイクルを実行する callHook(vm, 'created') 実際、焦点は initState(vm) メソッドにあり、このメソッドでは、vm インスタンスの $props、$data、$methods、computed、watch などが初期化されます。同時に、その内部で initData() メソッドが呼び出され、observer() メソッドを呼び出して、データ内のすべてのデータをレスポンシブ データに変換します。つまり、データ インターセプターを追加します。 したがって、create ライフサイクルの前に、vm の $props、$data、$methods、computed、および watch プロパティが初期化されることがわかります。 作成したライフサイクルが完了したら、下を見続けます ここでは、vm.$options.el が存在するかどうか、また vm.$options.el が何であるかが判断されていることがわかります。 新しいVue({ el: '#app' ルーター、 店、 レンダリング: h => h(App) }) したがって、vm.$options.el は上記で渡された el です。 すると誰もが好奇心を持つでしょうが、それが存在しないと、行き詰まり、前に進めなくなります。はい、そうでない場合は続行されません。コードを続行したい場合は、$mount メソッドを実行する必要があります。 新しいVue({ ルーター、 店、 レンダリング: h => h(App) }).$mount('#app') ここではelは渡されないので、ソースコード 絶対に去りません。ただし、新しい Vue を作成する場合、ユーザーは新しく作成された Vue インスタンスを使用して $mount を呼び出すことができます。このように、弊社の公式ウェブサイト上のライフサイクル図を理解しやすくなるかもしれません。 さて、次に進みましょう。次のステップは$mountを実行することです。$mountメソッドを見てみましょう 2.3、$mount関数以前初期化したときに $mount を上書きしたことを覚えていますか? そのため、今 $mount を実行すると、上書きされたマウントが実行されます。 ここでは、書き換え前に書き換え前のマウントメソッドを保存し、最後に書き換え前のマウントメソッドを呼び出します。 このステップの主な機能は、レンダリング機能があるかどうかを判断することです。 そうでない場合は、まずテンプレートがあるかどうか (options.template が存在するかどうか、options.template は id セレクターまたは dom である可能性があるかどうか) を判断します。テンプレートが存在する場合は、テンプレート内のコンテンツが取得され、テンプレートに割り当てられます。options.template が存在しない場合は、el で指定された dom がテンプレートとして使用され (つまり #app)、el の下の dom が取得され、テンプレートに割り当てられます。 テンプレートがDOMを取得した後、テンプレートをレンダリング関数にコンパイルし、コンパイルされたレンダリング関数をoptions.render属性の下にマウントします。 その後、書き換え前に $mount の実行を継続します。これを理解すると、ライフサイクル図の他の部分を理解できます。 2.4、マウント前次に、書き換え前の$mount関数の実行を見てみましょう。 \$mountは主に関数mountComponentを実行していることがわかります。mountComponent関数を続けて見てみましょう。 この関数は主に以下の 4 つのことを行うことがわかります。1 つずつ見ていきましょう。 2番目: .vueファイルはレンダリングにコンパイルされます この方法では、レンダリング関数が渡され、関数内で h 関数が使用される前に App.vue ファイルが実行されます。 3番目に、テンプレートをレンダリング関数にコンパイルします。
操作後の結果は、_update メソッドにパラメータとして渡されます。前に述べたように、_render メソッドはレンダリング関数を内部的に仮想 DOM にレンダリングするため、_render() の戻り値は vnode になります。 まず、_render() 関数内でレンダリング関数が仮想 DOM に変換される方法を見てみましょう。 それでは、_update関数内で何が行われているかを見てみましょう。 _update 関数では、__patch__ メソッドが実行され、新しい DOM と古い DOM の 2 つが比較され、違いが発見されて実際の DOM が更新されていることがわかります。最初のレンダリングの場合は、現在の vnode が直接使用され、実際の DOM が生成されます。 したがって、updateComponent メソッド全体の主な機能は、レンダリング関数をレンダリングして DOM を更新することであると結論付けられます。 3. 新しいウォッチャーインスタンスを作成する 新しいウォッチャー インスタンスが作成されると、updateComponent 関数がパラメーターとして渡されることがわかります。 ウォッチャーには、レンダリング ウォッチャー、$watch 関数ウォッチャー、計算ウォッチャーの 3 種類があります。ここでレンダリングするページはレンダリングウォッチャーです 上記では、渡した関数をゲッターに渡しています 下に行くとget()が呼び出されます get() は渡した関数を呼び出し、渡した関数はレンダリング関数であり、仮想 DOM をトリガーして実際の DOM を更新し、返された値はレンダリング後の実際の DOM であり、最終的に this.value に割り当てられ、依存関係を更新するために使用されることがわかります。現在の天気インスタンスはメインの vue インスタンスのウォッチャーなので、ページ全体のウォッチャーとして理解できます。 this.$fouceUpdate() を呼び出すと、このインスタンスの update メソッドが呼び出され、ページ全体が更新されます。 さて、下を見続けましょう 内部的には、vm._isMounted が true (つまり、Mounted フックが実行された) であり、vm._isDestroyed が false (つまり、現在のコンポーネントが破棄されていない) であるかどうかが判断されます。この時点で更新が発生した場合、最初のレンダリングではないことを意味するため、beforeUpdate フックが実行され、後で必ず updated が実行されます。ここではアップデートについては話しません。 新しいウォッチャーの後もコードはダウンし続ける 現在の vnode が null の場合、仮想 DOM が以前に生成されていないことを意味し、これは間違いなく最初のレンダリングであることを意味します。この時点で、vm._isMounted は true に設定されています。そしてマウントされたフック関数を実行すると、この時点で最初のレンダリングが完了します。 2.5、マウントマウント前からマウントまでの全プロセスで行われる主な作業は、 これが最初のレンダリングの全体のプロセスです。 Vue の初回レンダリングの全プロセスに関するこの記事はこれで終わりです。Vue の初回レンダリングに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: データベース復旧エラーの原因となる MySQL 文字セットの簡単な分析
>>: Nginx10m+の高並列カーネル最適化に関する簡単な説明
MySQL が複数のテーブルを結合するときに、次のエラーが報告されます: [Err]1267 – 操...
Nginx 仮想ドメイン名設定を使用すると、ドメイン名を購入せずに特定のドメイン名を介してローカル ...
EXPLAIN ステートメントは、MySQL クエリ ステートメント プロセスと EXPLAIN ス...
序文:前回の記事では、注意深い学生であれば発見できたかもしれない DDL ステートメントの使用法を中...
序文プロジェクトを .net core に移行した後、 System.Drawing.Commonコ...
1. 問題の説明: MysqlERROR1698 (28000) の解決方法、新しくインストールされ...
目次セットは値が重複しない特別なコレクションです。セットコレクション基本API独自の価値判断セットを...
Awk はテキスト ファイルを処理するためのアプリケーションであり、ほぼすべての Linux システ...
例:場所のルートとエイリアスルートディレクティブは、ルートによって設定されたディレクトリに検索ルート...
歴史ルート履歴モードとは、HTML5 の履歴 API を使用してクライアント側ルーティングを実装する...
目次インストール構成よくある間違い事前テスト作業依存関係の扱いインスタンスとDOMを生成する要約する...
この記事の例では、ログインと登録機能を実装するためのjsの具体的なコードを参考までに共有しています。...
コアはmysqldumpとランタイムです操作は実際にはそれほど難しくありません。バックアップ操作を実...
in() の ID の順序に従った Mysql クエリ結果の順序の詳細な説明コード例: <se...
JSX を使用してコンポーネント システムを構築する前に、例を使用してコンポーネントの実装原理とロ...