ホームページ > ウェブフロントエンド > Vue.js > [編集して共有] Vue の面接でよくある質問 (回答分析付き)

[編集して共有] Vue の面接でよくある質問 (回答分析付き)

青灯夜游
リリース: 2023-02-06 20:14:40
転載
2744 人が閲覧しました

今回は、基本的な知識を整理し、Vue の知識の蓄えを強化するために、Vue に関する面接でよくある質問をいくつか紹介します。

[編集して共有] Vue の面接でよくある質問 (回答分析付き)

Vue のよくある面接の質問の概要

MVVM モデル?

MVVM は Model-View-ViewModel の略称で、本質的には MVC モデルのアップグレード バージョンです。このうち、Model はデータ モデルを表し、View は表示されたページを表し、ViewModelViewModel# の間にあります。 ## Bridge では、データは ViewModel レイヤーにバインドされ、データがページに自動的にレンダリングされます。ビューが変更されると、ViewModel レイヤーにデータを更新するように通知されます。以前は DOM を操作してビューを更新していましたが、現在は data-driven view になっています。

Vue のライフ サイクル

各 Vue コンポーネント インスタンスは、作成後に一連の初期化プロセスを実行します。このプロセス中に、ライフ サイクル フックと呼ばれる関数によって、これにより、ユーザーは特定の段階で独自のコードを追加する機会が得られます。

Vue のライフ サイクルは、作成前後、マウント前後、更新前後、破棄前後、およびいくつかの特別なシナリオのライフ サイクルの 8 段階に分けることができます。 Vue 3 では、デバッグとサーバーサイド レンダリング用の 3 つの新しいシーンも追加されています。 [関連する推奨事項:

vuejs ビデオ チュートリアル Web フロントエンド開発 ]

Vue 2 のライフ サイクルVue 3 のライフサイクル説明作成前、作成後、beforeMountbeforeMountDOM が見つかります mountedmounted# にコンパイルされます が作成され、アクセス データと beforeUpdateupdated #beforeDestroy破壊##破壊後は、一部のタイマーまたはサブスクリプションのキャンセルに使用できます##activatedactivatedkeep-alivedeactivatedkeep-aliveerrorCapturedリアクティブな依存関係が収集されるときに呼び出されるデバッグ フック リアクティブな依存関係がトリガーされたときに呼び出されるデバッグ フック serverPrefetchコンポーネント インスタンスがサーバー転送でレンダリングされる前に
beforeCreate beforeCreate datamethods のデータはまだ初期化されていません
created created data に値がありますが、まだマウントされていません。いくつかの # を実行できます。 ##Ajax マウントする前に、
をリクエストします。 Render
# #マウント後、DOMDOM 要素の取得に使用できます
beforeUpdate 更新前、更新前のさまざまなステータスを取得するために使用できます
updated 更新後、すべてのステータスは最新の状態になります
beforeUnmount 破棄する前に一部のタイマーまたはサブスクリプションをキャンセルするために使用できます
#アンマウント
キャッシュされたコンポーネントがアクティブ化されたとき deactivated
キャッシュされたコンポーネントが非アクティブ化されたとき errorCaptured
子孫コンポーネントからエラーをキャプチャするときに呼び出されます #renderTracked
renderTriggered
#—
##

親コンポーネントと子コンポーネントのライフ サイクル:

  • 読み込みとレンダリングのフェーズ: 親の作成前 -> 親の作成 ->親 beforeMount -> 子 beforeCreate -> 子作成 -> 子 beforeMount -> 子マウント -> 親マウント
  • 更新フェーズ : 親 beforeUpdate -> 子 beforeUpdate - > 子が更新されました -> 親が更新されました
  • 破棄フェーズ: 親 beforeDestroy -> 子 beforeDestroy -> 子破棄 -> 親破棄

Vue.$nextTick

次の DOM 更新サイクルの後に遅延コールバックを実行します。データを変更した直後にこのメソッドを使用して、更新された DOM を取得します。

nextTick は Vue によって提供されるグローバル API です。Vue の非同期更新戦略により、データの変更は DOM に直接反映されません。現時点では、必要に応じて更新された DOM 状態をすぐに取得するには、このメソッドを使用する必要があります。

Vue は、DOM の更新時に非同期で実行されます。データが変更されると、Vue は非同期更新キューを開き、同じイベント ループ内で発生するすべてのデータ変更をバッファーに入れます。同じ watcher が複数回トリガーされた場合、キューにプッシュされるのは 1 回だけです。バッファリング中のこの重複排除は、不必要な計算や DOM 操作を回避するために重要です。 nextTick メソッドはコールバック関数をキューに追加し、前の DOM 操作が完了した後にのみ関数が呼び出されるようにします。

使用シナリオ:

  • データを変更した直後に更新された DOM 構造を取得したい場合は、Vue を使用できます。 nextTick ()

  • created ライフ サイクルで DOM 操作を実行します

##Vue インスタンスのマウント プロセス中に何が起こりますか?

マウント プロセスは

app.mount() プロセスを参照します。これは初期化プロセスです。全体として 2 つのことを実行します: Initialization更新メカニズムを確立します

初期化では、コンポーネント インスタンスが作成され、コンポーネントの状態が初期化され、さまざまな応答データが作成されます。

更新メカニズムを確立するこのステップでは、コンポーネントの更新関数がすぐに実行されます。これにより、コンポーネントのレンダリング関数が初めて実行され、

patchConvert vnode##が実行されます。 # to dom ; 同時に、レンダリング関数を初めて実行すると、その内部応答データとコンポーネント更新関数の間に依存関係が作成され、将来データが変更されたときに、対応するアップデート機能が実行されます。

Vue のテンプレート コンパイル原理

Vue には

compiler

と呼ばれる独自のコンパイラ モジュールがあり、その主な機能はユーザーをコンパイルすることです。 #template は、js の実行可能な render 関数にコンパイルされます。 Vue では、コンパイラは最初に template を解析します。このステップは
parse と呼ばれ、終了後に abstract と呼ばれる JS オブジェクトが取得されます。構文ツリー AST; 次に、AST の深い処理の変換プロセスがあり、このステップは transform と呼ばれ、最後に以前に取得された AST は次のようになります。これも render 関数です。 Vue の応答性の原則

Vue 2 のデータ応答性は、データ型に応じて異なる方法で処理されます。オブジェクトの場合は、
    Object.defineProperty(obj,key,descriptor)
  • を通じてオブジェクト プロパティ アクセスをインターセプトします。データがアクセスまたは変更されると、感知して反応します。配列の場合は、配列プロトタイプを上書きします。 . メソッドを拡張し、7 つの変更メソッド (プッシュ、ポップ、シフト、アンシフト、スプライス、ソート、リバース) を拡張して、これらのメソッドが追加で更新通知を実行して応答できるようにします。

    欠点:
    初期化中の再帰的走査によりパフォーマンスが低下します。

      通知更新プロセスでは、多数の
    • dep
    • インスタンスと ## を維持する必要があります。 #watcher
    • たとえば、多くの追加メモリを消費します; オブジェクト プロパティの追加または削除はインターセプトできず、Vue.set
    • delete などの API が必要です
    • 有効にします; ES6 で新しく生成された
    • Map
    • および Set データ構造はサポートされていません。
    • Vue 3 は、
    ES6
  • Proxy

    メカニズムを使用して、応答性が必要なデータをプロキシします。オブジェクトと配列を同時にサポートできます。動的な属性の追加と削除はインターセプトできます。すべての新しいデータ構造がサポートされています。オブジェクトのネストされた属性は実行時に再帰的であり、使用されるときのみプロキシされます。特に大規模な属性を維持する必要はありません。依存関係の数が減り、パフォーマンスが大幅に向上しました。大きな進歩です。

    仮想 DOM

概念:

仮想 DOM は、名前が示すように、仮想 DOM オブジェクトです。 、それ自体は JS オブジェクトであり、さまざまな属性を通じてビュー構造を記述するだけです。
  • 仮想 DOM の利点:
    (1) パフォーマンスの向上
    DOM を直接操作するには制限があります。実際の要素には多くの属性があります。直接操作すると、 will 多くの余分な属性コンテンツが操作されますが、これは不必要です。これらの操作が JS オブジェクトに転送されると、はるかに簡単になります。さらに、DOM の操作には比較的コストがかかり、DOM 操作が頻繁に行われると、ページの再描画やリフローが簡単に発生する可能性があります。中間処理が抽象 VNode を通じて実行される場合、直接 DOM 操作の数が効果的に削減され、それによってページの再描画とリフローが削減されます。
    (2) 便利なクロスプラットフォーム実装
    同じ VNode ノードを、異なるプラットフォーム上の対応するコンテンツにレンダリングできます。例: ブラウザーでレンダリングされる場合、それは DOM 要素ノードであり、ネイティブでレンダリングされる場合 ( iOS、Android)対応コントロールとなります。 Vue 3 を使用すると、開発者は VNode に基づいてカスタム レンダラーを実装し、さまざまなプラットフォームでのレンダリングを容易にすることができます。

  • 構造:
    統一された標準はなく、通常は tagpropschildren## が含まれます。 # 3 つのアイテム。
    タグ: 必須。これはラベルである場合もあれば、コンポーネントや関数である場合もあります。
    props: オプション。このラベルのプロパティとメソッドです。
    children: オプション。これは、このタグのコンテンツまたは子ノードです。テキスト ノードの場合は文字列、子ノードがある場合は配列です。つまり、children が文字列であると判断された場合、それはテキスト ノードである必要があり、このノードには子要素があってはいけないことを意味します。

diff アルゴリズム

1. 概念:

diffアルゴリズムは比較アルゴリズムでは、古い仮想 DOM と新しい仮想 DOM を比較することで、どの仮想ノードが変更されたかを知ることができます。この仮想ノードを見つけて、他の変更されていないノードは更新せずに、この仮想ノードに対応する実ノードのみを更新します。正確に更新するノード実際の DOM を使用できるため、効率が向上します。

2. 比較方法:

diffアルゴリズムの全体的な戦略は次のとおりです: 深さ優先、同じレイヤーの比較。比較は同じレベルでのみ実行され、レベル間では比較されません。比較プロセス中に、ループは両側から中央まで縮小します。

    まず、2 つのノードの
  • tag が同じかどうかを確認し、異なる場合はノードを削除し、ノードを再作成して置き換えます。
  • tag同じ場合は、まず属性を置き換えてから、サブ要素を比較します。これらの要素は、次の状況に分けられます。新しいノードにサブ要素がある場合は、ダブル ポインター方法が比較に使用されます。新旧の先頭ポインタと末尾ポインタを比較し、中央に近づくようにループし、状況に応じて patchVnode
      を呼び出し、
    • patch プロセスを繰り返し、createElem を呼び出して作成します新しいノードを作成し、ハッシュ テーブルから新しいノードを作成します。 key の一貫した VNode ノードを見つけて、状況に応じて操作します。 新しいノードには子要素があり、古いノードには子要素がありません。子要素の仮想ノードを実ノードに変換して挿入するだけです。
    • 新しいノードには子要素がなく、古いノードには子要素がある場合、子要素はクリアされ、新しいノードのテキスト コンテンツに設定されます。
    • 古いノードと新しいノードに子要素がない場合、つまり両方がテキスト ノードである場合、テキストの内容が直接比較され、異なる場合は更新されます。
  • #Vue におけるキーの役割は何ですか?

key

は主に、仮想 DOM

をより効率的に 更新するために使用されます。 Vue が 2 つのノードが同じかどうかを判断する場合、主に 2 つのノードの key

要素タイプ tag を判断します。したがって、key が設定されていない場合、その値は未定義であり、これらは常に 2 つの同一のノードであるとみなされ、更新操作のみが実行できるため、大量の DOM 更新操作が発生します。 。 コンポーネント内のデータが関数であるのはなぜですか?

new Vue() では、ルート インスタンスが 1 つしかなく、データ汚染が発生しないため、関数またはオブジェクトにすることができます。

コンポーネントでは、データは関数である必要があります。その目的は、複数のコンポーネント インスタンス オブジェクトが同じデータを共有してデータ汚染を引き起こすことを防ぐことです。関数の形式では、ファクトリ関数として返されます。 initData が使用される場合、まったく新しいデータ オブジェクト。

Vue でコンポーネント間で通信するにはどうすればよいですか?

親コンポーネントと子コンポーネント間の通信:
  • 親は

    props

    を介して子にデータを渡し、子はデータを子に渡します。

    $emit Trigger イベントを介して親。通信は親チェーン/子チェーン ($parent/$children) を介して行うこともできます。ref コンポーネント インスタンス (provide/inject;$attrs/$listeners) にアクセスすることもできます。

    姉妹コンポーネント通信:
  • グローバル イベント バス

    EventBus

    Vuex

    クロスレベルコンポーネント通信:
  • グローバルイベントバス

    EventBus

    Vuexprovide / 注入

v-show と v-if の違いは何ですか?

  • #制御方法が異なります。

    v-show は、CSS 属性 display: none を要素に追加することによって行われますが、要素はまだ存在します。一方、v-if は、要素の表示または非表示を制御します。要素全体を変更して要素を追加または削除します。

  • #コンパイルプロセスが異なります。
  • v-if

    切り替えには部分的なコンパイル/アンインストール プロセスがあります。切り替えプロセス中に、内部イベント リスナーとサブコンポーネントが適切に破棄され、再構築されます。v-show は単なる単純な CSS です。 -ベースの切り替え。

    #コンパイル条件が異なります。
  • v-if
  • は、真の条件付きレンダリングです。条件付きブロック内のイベント リスナーとサブコンポーネントが、切り替えプロセス中に適切に破棄され、再構築されることが保証されます。レンダリング条件が false の場合、操作は実行されるまで実行されません。真実のためにレンダリングします。

    #トリガーのライフサイクルが異なります。

    v-show
  • false から true に変更する場合、コンポーネントのライフサイクルはトリガーされません;
  • v-if

    false から true に変更する場合、コンポーネントの beforeCreate# #、createdbeforeMountmounted フックは、から変更するときにコンポーネントの beforeDestorydestoryed# をトリガーします。 true から false。##フック。 パフォーマンスの消費は異なります。 v-if はスイッチング コストが高く、

    v-show
  • は初期レンダリング コストが高くなります。
  • 使用シナリオ: 非常に頻繁に切り替える必要がある場合は、v-show

    を使用することをお勧めします。たとえば、アコーディオン メニュー、タブ ページ、等。; 実行時に条件がほとんど変化しない場合は、
  • v-if
を使用することをお勧めします。たとえば、ユーザーがログインした後、異なる権限に応じて異なるコンテンツが表示されます。


computed と watch の違いは何ですか?

computed計算されたプロパティは、他のプロパティに依存して値を計算します。内部依存関係が変更されると関数が再実行されます。計算されたプロパティはキャッシュされ、複数回再利用できます。属性を計算するとき、戻り値はキャッシュから取得されます。計算された属性には return

キーワードが必要です。
  • watch 特定のデータの変更をリッスンして関数をトリガーします。データがオブジェクト型の場合、オブジェクトの属性値が変更されたときにディープ リスニング deep 属性を使用する必要があります。また、ページが変更されたときに即時リスニング
  • immdiate
  • 属性を使用することもできます。が最初にロードされます。 アプリケーション シナリオ: 計算されたプロパティは通常、テンプレートのレンダリングで使用されます。特定の値は他の応答オブジェクトや計算されたプロパティに依存しますが、リスニング プロパティは特定の値を観察するのに適しています。複雑なビジネス ロジックを完成させます。
  • v-if と v-for を一緒に使用することが推奨されないのはなぜですか?


Vue 2 では、

v-for

v-if よりも高い優先順位を持っています。つまり、

v-if

は繰り返し実行されます。各 v-for ループで実行します。走査される配列が大きく、表示される実際のデータが非常に小さい場合、パフォーマンスが大幅に無駄になります。 Vue 3 では、まったく逆です。v-ifv-for よりも優先度が高いため、

v-if## の場合、 # が実行されると、呼び出される変数はまだ存在しないため、例外が発生します。

通常、この問題が発生する状況は 2 つあります。 リスト内の項目をフィルタリングするには、たとえば次のようにします。 v-for = "user in users" v -if = "user.active"。この場合、計算されたプロパティを定義して、フィルター処理されたリストを返すことができます。

非表示にする必要があるリストのレンダリングを避けるため (例:

v-for = "user in users" v-if = "showUsersFlag"
    )。この場合、
  • v-if をコンテナ要素に移動するか、template
  • のレイヤーでラップすることができます。
  • #$setレスポンシブ データを手動で追加して、データ変更ビューが更新されない問題を解決できます。配列内の項目の値を直接設定するか、プロジェクト内のオブジェクトのプロパティの値を直接設定すると、ページが更新されないことがわかります。これは、データの変更を監視できない Object.defineProperty()
  • の制限によるもので、
this.$set(array or object, array subscript or object’s property name, updated value ) を使用できます。 ###解決する。

キープアライブとは何ですか?

  • 機能: コンポーネントのキャッシュを実装し、コンポーネントのステータスを維持し、レンダリングの繰り返しによって引き起こされるパフォーマンスの問題を回避します。
  • 動作原理: Vue.js は内部的に DOM ノードを個々の VNode ノードに抽象化します。keep-aliveコンポーネントのキャッシュも VNode ノードに基づいています。条件を満たすコンポーネントをキャッシュオブジェクトにキャッシュし、再レンダリング時にはキャッシュオブジェクトからVNodeノードを取り出してレンダリングします。
  • 次の属性を設定できます:
    include: 文字列または通常。一致する名前を持つコンポーネントのみがキャッシュされます。
    exclude: 文字列または正規表現、名前が一致するコンポーネントはキャッシュされません。
    max: 数値、キャッシュできるコンポーネント インスタンスの最大数。
    マッチングでは、最初にコンポーネントの name オプションがチェックされます。name オプションが使用できない場合は、そのローカル登録名 (親コンポーネントのコンポーネント オプションのキー値) と一致します。匿名コンポーネントは一致できません。

キャッシュされた keep-alive を持つコンポーネントには、さらに 2 つのライフサイクル フック (activateddeactivated) が含まれます。
初めてコンポーネントに入る場合: beforeCreate --> created -->beforeMount -->mounted -->activated -->gt; beforeUpdate --> updated -->deactivated
コンポーネントをもう一度入力してください。これは、Vue コンポーネントで再利用可能な機能を配布するための非常に柔軟な方法を提供します。

使用シナリオ: いくつかの同一または類似のコードが異なるコンポーネントで使用されることが多く、これらのコードの機能は比較的独立しています。同じまたは類似のコードは、ミックスインを通じて抽出できます。 欠点:

不明瞭な変数ソース

複数のミックスインにより名前の競合が発生する可能性があります (解決策: Vue 3 Combination API)

  • ミックスインとコンポーネント ピットの間には複数のペアの関係があり、プロジェクトがより複雑になります。

  • スロット
  • slot
  • スロットは通常コンポーネント内で使用されますが、コンポーネントをカプセル化する場合は使用されません。この位置に表示される要素の形式を決定するときは、
slot

を通じてこの位置を占有することができます。この位置の要素は、親コンポーネントからコンテンツの形式で渡す必要があります。 slot は次のように分割されます:

##Default slot: サブコンポーネントは <slot> タグを使用してレンダリング位置を決定し、ラベル You DOM 構造をバックアップ コンテンツとして内部に配置できます。親コンポーネントが使用されている場合、子コンポーネントのタグにコンテンツを直接書き込むことができ、コンテンツのこの部分が ## に挿入されます。子コンポーネントの #<slot>

タグの位置。コンテンツをスロットに渡さずに親コンポーネントが使用される場合、バッキング コンテンツがページに表示されます。
  • 名前付きスロット: サブコンポーネントは、name 属性を使用してスロットの名前を表します。スロットで name が指定されていない場合、非表示になります。含まれる名前は default です。親コンポーネントで使用される場合、
  • v-slot
  • ディレクティブは、デフォルトのスロットに基づいて要素を配置する必要があるスロットを指定するために使用されます。子コンポーネントのスロット番号 ##name属性値。 v-slot ディレクティブを使用して、要素を配置するスロットを指定します。このディレクティブは、