ホームページ >ウェブフロントエンド >Vue.js >【編集・要約】Vueの面接でよく聞かれる20の質問

【編集・要約】Vueの面接でよく聞かれる20の質問

青灯夜游
青灯夜游転載
2022-10-17 20:20:272335ブラウズ

【編集・要約】Vueの面接でよく聞かれる20の質問

プログラマーとして、好きな仕事を見つけたい場合は、必然的に 8 部構成のエッセイをたくさん質問することになります。中には仕事と関係のないものもありますが、あなたは面接に合格したければ、それを知らなければなりません。そこで私は最近、面接での質問をいくつかまとめ始めました。それは、第一に自分の理解を深め、良い仕事を見つけるためであり、第二に、できるだけ多くの友人が関連知識を迅速に習得し、面接に無事に合格できるよう手助けするためです。

この記事では、vue に関する一般的な問題をいくつか紹介します。これらの質問を難易度や関連性に応じて整理し、理解しやすくするようにしています。もちろん、この記事は単なる八本足エッセイのような単純なものではなく、これらの知識は仕事でもよく使われます。 [関連する推奨事項: vuejs ビデオ チュートリアル ]

vue ライフ サイクル

この質問は一般にあまり聞かれませんが、もし聞かれた場合は、必ず回答してください

回答

##beforeCreate-onBeforeMountonMountedonBeforeUpdate #データ更新前に呼び出されるデータ更新後に呼び出される#beforeDestroyonBeforeUnmountコンポーネントの破棄前に呼び出されましたdestroyedonUnmountedコンポーネントの破棄 呼び出しの完了

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

これは前の質問よりも少し複雑です。メモリを理解しようとすることも、直接記憶することもできます

レンダリングプロセス

#
父beforeCreate
父created
父beforeMount
子beforeCreate
子created
子beforeMount
子mounted
父mounted

更新プロセス

父beforeUpdate
子beforeUpdate
子updated
父updated

破壊プロセス

父beforeDestroy
子beforeDestroy
子destroyed
父destroyed

注意子コンポーネントが非同期コンポーネントの場合、その実行順序は変わります。親コンポーネントのライフサイクルが最初に実行され、次に子コンポーネントのライフサイクルが実行されます。

v-if と v-show

この質問は非常に基本的な質問であり、理解するのは簡単です。面接では通常、これら 2 つの指示の違いとシナリオが何であるかを尋ねます。どのコマンドが適切ですか? 回答

  • v-if は dom 要素が作成されるかどうかを示し、v-showこの dom 要素の display 属性が none

  • ステータスが頻繁に切り替わる場所で一般的に使用されるv-show,v-if は、スイッチング オーバーヘッドが比較的大きいため、条件が頻繁に変化しないシナリオに適しています。 ##v-for および v-if の優先順位

この質問は比較的頻繁に聞かれますが、実際の開発ではこのように使用されません。

回答

一般的に、開発中に同じタグ内で同時に v-for と v-if を使用することはお勧めできません。 process

  • Vue2 では v-for の優先度が高くなるため、先にループが実行され、その後 v-if 判定が行われるため、全体がList

  • Vue3 では v-if の優先順位が高くなりますが、配列を走査する場合は、 v-if の判定は配列内の要素に基づいて行われます。v-if が最初に実行され、この時点では配列が取得されていないため、エラーが報告されます。したがって、これを Vue3 で使用することはまだ推奨されていません。実際の作業なので質問します。非常にたくさんありますが、理解していれば基本的に答えることができます。

  • computed

    は計算された属性であり、次のことが可能です。属性が 1 つ以上の属性の影響を受ける場合に使用されます。.
  • watch
はリスナーです。属性の変更に基づいて何らかの処理を行う必要がある場合、

watch を使用して次のことができます。この属性を監視します

    computed
  • にはキャッシュの特性があり、依存するプロパティが変更された場合にのみ内部ロジックを再実行します。 code

    <template>
        <div>{{ addSum }}</div>
        <div>{{ addSum }}</div>
        <div>{{ addSum }}</div>
    </template>
    <script setup>
    import { computed, ref, watch } from "vue";
    const a = ref(1)
    const b = ref(2)
    let addSum = computed(() => {
        console.log('内部逻辑执行')
        return a.value + b.value
    })
    </script>
    このページは複数回使用されますaddSumですが、「内部ロジックの実行」は 1 回だけ印刷されます
  • #watch

    デフォルトは、ページが最初に読み込まれるときに実行されません。immediate:trueを設定する必要があります。監視は初めて実行されます。

watchデフォルトでは、データの 1 つのレイヤーのみが監視され、複数のレイヤーは監視されません。データ内の属性の変更は

deep:true## に設定する必要があります# 詳細なモニタリングを実行するには
  • vue-router

    vue-router
  • について、次のような質問がたくさんあります。実装原理としては、ルートジャンプ、ルートガードなどがあるので、システムを確認することをお勧めします
  • vue-router

    Documentation 質問 1: vue-router とは、その原理を説明してください?

  • Vue Router は、Vue の公式ルーティング マネージャーです。ハッシュと履歴の 2 つのモードがあります。

hash モードは、監視

hashchange# を使用します。 ## イベントは、ページ コンテンツの一部を更新するために使用されます。URL の後に

# が続きます。history

モードは、## をリッスンすることによって実行されます。 #popstate

イベント。ページ コンテンツの一部を更新する動作原理は hash モードと似ていますが、URL の後に

# が表示されない点が異なります。より美しく。同時に問題も発生し、

# という番号がないため、ユーザーがページを更新するとサーバーにリクエストが送信され、リソースに対する 404 リクエストが発生します。 , nginx の設定が必要です。すべてのルートをルート ページにリダイレクトします質問 2: ルーティング ジャンプ方法は何ですか?

#組み込みコンポーネントジャンプrouter.push({ path: '/home' }) ,router.replace({ path: '/home' })

質問 3: ルーティング ガードについて教えてください。 #ルート ガードは、

グローバル ルート ガード
  • ルート専用ガード

    コンポーネント ルート ガード
  • に分かれています。 ##グローバル ルート ガード

    ##beforeEach
  • は、各ルート ジャンプがトリガーされる前に、
to、from、next

の 3 つのパラメーターを受け取ります。

beforeResolve は、ログイン検証中によく使用されます。beforeEach と似ています。違いは、ナビゲーションが確認される前に、次の時点で行われることです。同時に

    afterEach は、すべてのコンポーネントのガードと非同期ルーティング コンポーネントが解析された後に呼び出され、ルーティング ジャンプが完了した後に呼び出され、
  • との間で 2 つのパラメーターを受け取ります。
  • ルート排他ガード

    ##beforeEnter、通常はルーティング設定ファイル (router/index.js) で設定され、入力前に関連します特定のルートが運行されます

    • 组件路由守卫

    接收to、from、next三个参数

    • beforeRouteEnter,进入该组件之前调用,无法获取到vue实例

    • beforeRouteUpdate,在当前路由改变,但是该组件被复用时调用

    • beforeRouteLeave, 在离开当前组件时调用

    vue2和vue3区别

    当面试问你会用vue3吗,如果你回答会用的话,那么大概率会问vue2和vue3有哪些区别,最近我去面试的时候百分之90都问了这个问题。

    回答

    • 写法上的区别:vue2使用的是options(选项)Api,vue3的是composition Api(当然vue3也兼容composition api)。options Apimethods,compute,data等api都是分散的。而composition api中的代码是根据逻辑功能来组织的,我们可以将一个功能所定义的methods,compute,data等api会放在一起,让我们可以更灵活地组合组件逻辑。

    • vue2将响应式数据放到data函数中,而vue3则是使用refreactive将数据声明为响应式

    • 响应式实现方式:vue2中是通过Object.defineProperty对数据劫持实现的,vue3中则是使用Proxy对数据代理实现的。

    • 生命周期区别:vue3中将beforeCreatecreated合并到了setup函数中

    • 根节点: vue3组件允许多个根节点,而vue2只允许一个

    • 内置组件: vue3新增了传送组件Teleport和异步依赖处理组件Suspense

    vue插件使用

    面试一般会问你如何写一个vue插件,所以没写过vue插件的最好去亲自体验一下

    回答:

    vue实例会有一个use函数,它接受的是一个带有install函数的对象和一个可选的选项对象,当我们使用 vue.use(plugin)或者app.use(plugin)会调用我们插件的install属性的函数,并且将当前组件的实例传进来.所以在插件中就可以对这个实例进行一些操作来实现我们插件的功能

    vue插槽

    插槽slot可以理解为占坑,当使用一个组件的时候,在组件标签里的对应的内容就会替换掉这个组件中的slot标签。

    插槽分为默认插槽具名插槽作用域插槽

    默认插槽子组件中用slot标签来确定渲染位置,父组件使用它时直接在子组件的标签内写入内容即可

    //子组件
    <template>
        <slot />
    </template>
    
    //父组件
    <Child>
      <div>默认插槽</div>  
    </Child>

    具名插槽

    顾名思义就是具有名字的插槽,子组件中可以用name熟悉对slot命名,父组件在使用的时候通过template中的v-slot:name或者#name来定义这个插槽中的内容

    //子组件
    <template>
      <slot name="content"></slot>
    </template>
    
    //父组件
    <Child>
        <template v-slot:content>具名插槽内容</template>
    </Child>

    作用域插槽

    子组件中的slot可以通过类似组件属性传递的方式将子组件的值传递给父组件中这个子组件的插槽内容中(子组件标签内),在父组件使用子组件的时候要用v-slot的值进行接收这些参数,默认插槽可以将其直接写在子组件标签上,具名插槽则写在template上。而传过来的值只能在子组件标签中或者template标签中使用。所以在父组件作用域中获取到了子组件作用域中的变量,可以认为作用域插槽延伸了子组件数据的作用范围,因此叫做作用域插槽

    如果你想详细理解插槽的作用可以阅读这篇文章Vue3中插槽(slot)用法汇总 - 掘金 (juejin.cn)

    组件通信

    这里我大概归纳了一下vue2和vue3的传参方式

Vue2(オプションのAPI) Vue3(セットアップ) 説明
##- インスタンス作成前 # created
インスタンスの作成後 beforeMount
DOM がマウントされる前に呼び出されます。 mounted
DOM マウント完了呼び出し beforeUpdate
#updated onUpdated
#メソッドVue2Vue3父から息子へ小道具#息子から父へ#$emitemits父から息子へ$attrsattrs息子から父へ$リスナーなし (attrs モードにマージ)父から子provide/injectprovide/inject子コンポーネントは親コンポーネントにアクセスします$parentNone親コンポーネントは子コンポーネントにアクセスします$ ChildrenNoneref# #Brother コンポーネントが値を渡しますEventBusmitt

它们的具体用法可以参考我的这篇文章盘点Vue2和Vue3的10种组件通信方式(值得收藏) - 掘金 (juejin.cn)

除了上面的传参方式你也可以回答Vuex和Pinia,前提你了解这两个状态管理器,因为你说了大概率下个问题就会问你Vuex和Pinia

vuex

面试问到这个问题的时候,不要上来就开始说什么state,mutation...。你要先阐述Vuex干嘛用的,什么时候需要用Vuex。

回答

  • Vuex是Vue中的全局状态管理框架,它可以管理应用的所有组件的状态。并不是每个项目都需要引入Vuex的,当我们的项目有很多个页面,并且这些页面共享着多个数据状态,此时我们可以引入Vuex。

  • Vuex有三个核心的概念,state,mutations,actions,其中state为存放数据的地方,mutations中的函数作用则是用来修改stateactions中一般是用了处理一些异步操作的函数。

  • Vuex除了上面三个概念还有getters,moudlesgetters就像Vue中的计算属性computed一样用来描述依赖响应式状态state中的复杂逻辑。moudles则是可以将store分割成模块(module),每个模块都拥有自己的state,mutations,actions等,在大型应用中经常用到

  • 场景:当我们异步获取结果并赋值给state的时候,比如数据请求,我们可以在actions中进行数据请求,拿到结果通过它的dispatch方法调用mutations中修改state的函数,从而将结果赋值给了state

pinia

这个现在问的好像不多,从我最近面试来看只有我提到了才会问一下,但是以后问的肯定会越来越多。关于pinia问的一般是它和Vuex的区别,确切的说应该是它和Vuex4之间的区别

回答

pinia其实就是Vuex5,它和Vuex的主要区别有以下几点

  • Pinia使用更简单,更符合开发者的开发习惯

  • pinia中没有了mutations,状态state的修改可以直接进行修改,或者在actions中修改,或者使用它的$patch方法进行修改

  • pinia中没有了modules,如果想使用多个store,直接使用defineStore定义多个store传入不同的id即可

  • 更好的TS支持,不需要创建自定义的复杂包装器来支持TS

vue自定义指令

vue 官方提供了v-text、v-for、v-model、v-if 等常用的指令。除此之外vue 还允许开发者自定义指令。面试经常会问什么是自定义指令?你用自定义指令做过哪些功能?

回答1:什么是自定义指令?

  • 自定义指令包含局部指令和全局指令,在模板中使用指令前必须先使用directives选项注册。局部指令指在某个组件中注册,而全局则是将指令注册到全局,通常在main.js中注册。

  • 自定义指令由一个包含类似组件生命周期钩子的对象来定义。它的生命周期钩子包含created,beforeMount,mounted,beforeUpdate,updated,beforeUnmount,unmounted,

  • 常用的钩子为mounted 和 updated,它接受el,binding等参数.binding参数的值一般包含绑定到这个元素上的信息,比如下面这个指令

<div v-example:foo.bar="baz">

它的binding会是这个对象

 {
    arg: 'foo',
    modifiers: { bar: true },
    value: /* `baz` 的值 */,
    oldValue: /* 上一次更新时 `baz` 的值 */ 
 }

回答2:你用自定义指令做过哪些功能?

  • 数据埋点,通过绑定自定义事件传入点击当前元素需要埋点的事件名,在指令中监听当前元素的点击事件后调用后台接口将事件名传入

  • 权限控制,通过绑定自定义事件传入控制当前元素的权限字段,在指令中获取到当前元素根据权限字段来控制该元素的状态(显示,隐藏等)

  • ...

keep-alive

官网描述

<KeepAlive> は、複数のコンポーネント間を動的に切り替えるときに、削除されたコンポーネント インスタンスをキャッシュする機能を持つ組み込みコンポーネントです。

回答

  • 通常、コンポーネントを切り替えると、前のコンポーネントは破棄されます。また、 < を使用すると、前のコンポーネントが破棄されます。 KeepAlive>ラップすると、コンポーネントはキャッシュされ、コンポーネントが再度表示されたときに前の状態が保持されます。

  • keep-alive2 つの属性 includeexclude を受け取ります。これらはそれぞれ、キャッシュする必要があるコンポーネントと、キャッシュする必要があるコンポーネントを表します。キャッシュは必要ありません。コンポーネント名の配列、文字列、または正規表現を受け取ります。動的コンポーネント component またはルート router-view

    ## を使用するときに使用できます。
  • #keep-alive は、キャッシュ インスタンスの最大数を示す max 属性も受け取ります。この数を超えると、アクセスされていないキャッシュ インスタンスは、最も長い時間は破壊されます。

  • keep-alive には、activateddeactivatedactivated という 2 つのライフ サイクルがあります。フックは、初めてマウントされるとき、またはキャッシュから再挿入されるたびに呼び出されます。 deactivatedコンポーネントが DOM から削除されるか、コンポーネントがアンインストールされるとフックが呼び出されます

vue2 Mixin-Mixin

vue3 では

Mixin という概念がなくなったので、今後聞かれる機会はどんどん減っていきますが、それでも聞かれる頻度は非常に高いです。一般的に、その概念、利点と欠点について学び、場合によっては、そのライフサイクルの実行順序や親コンポーネントについても質問します。

vue 公式 Web サイトの説明:

Mixin は、Vue コンポーネントで再利用可能な機能を配布する非常に柔軟な方法を提供します。ミックスインには、任意のコンポーネント オプションを含めることができます。コンポーネントがミックスインを使用する場合、ミックスインのオプションはすべてコンポーネント自体のオプションに「混合」されます。

回答1.Mixinの機能は、コンポーネントの公開ロジックを抽出することです。どのコンポーネントを使用する必要がある場合、抽出したものを直接ミックスします。コンポーネントのすぐ内側にパーツを入れる 2. Mixin のライフ サイクルは、親コンポーネントのライフ サイクルより前に実行されます。Mixin のプロパティまたはメソッドが親コンポーネントと競合する場合、親コンポーネントが使用されます。 2. 利点: コードの冗長性を削減し、ロジックの再利用性を向上させることができます。 3. 欠点: 名前の競合が発生しやすく、ソースを追跡するのが難しく、後のトラブルシューティングが不便です。

vue 応答性の原則

この質問は非常に頻繁に寄せられます。この質問は、私が経験したほぼすべての面接で聞かれており、Vue では冒頭の質問です。

以下は、vue2 を例として挙げた、私自身の理解した答えです。参考にしてください。

    ##vue の応答原理は、
  • Object.defineProperty に基づいています。

    この API は、データをハイジャックし、パブリッシャー/サブスクライバー モデルと組み合わせて実装するために使用されます。

  • は、最初に
  • Object.defineProperty で

    get## を使用します。 #vue 内のデータのすべての属性にアクセスしてハイジャックする関数。これには、データ内のより深い属性のハイジャックが含まれ、ハイジャック メソッドを再帰的に呼び出す必要があります。これは、Observer クラス

    各属性をハイジャックした後、複数のサブスクライバがこの属性にバインドされます
  • watcher
  • 。この

    watcher には、ビューを更新する関数 update が含まれています。

  • watcher
  • と属性の対応関係やビューとの接続は、テンプレートの

    Compileクラスをコンパイルすることで実現されます。 Compile は dom オブジェクト全体を取得し、要素の子ノードを走査して vue の data 属性を取得します。その後、その属性に watcher を直接追加して、それにいくつかの更新を加えます。 Method.

    各属性
  • watcher
  • の複数のサブスクライバが、対応する配列に追加されます。ここでは、

    Deps クラスを使用します。実装すると、watcher を初期化するときに、DepsaddSub メソッドが呼び出され、watcher# に対応するこのクラスの Subs# が追加されます。 #配列内データ内のプロパティが変更されると、

    Object.defineProperty
  • set

    関数がトリガーされます。プロパティの Deps クラスの notify 関数が呼び出され、Subs 配列内のサブスクライバー watcher を走査し、その関数を呼び出します。 updateビューの更新をトリガーするには

    Object.defineProperty と proxy の違い

一般に、次のことができます。応答性の原則について質問した後に質問する 2 つの違い

Answer

##Object.defineProperty

はプロパティをプロキシすることしかできません,
    Proxy
  • プロキシはオブジェクトです。

    新しいプロパティがオブジェクトに追加され、Proxy

    はそれを監視できますが、
  • Object.defineProperty
  • は監視できません。

  • Object.defineProperty 的代理行为是在破坏原对象的基础上实现的,Proxy 则不会破坏原对象,只是在原对象上覆盖了一层。

  • 数组新增修改,Proxy可以监听到,Object.defineProperty不能。

  • Proxy不兼容IE11及以下

vue3内置组件

vue3新增了两个内置组件分别是TeleportSuspense

  • Teleport组件

可以称之为传送门,作用将其插槽内容渲染到 DOM 中的另一个位置,接收两个参数to(要去的位置)和disabled(是否留在原位置)。接收比如下面代码

<teleport to="#popup"> 
    <video src="./my-movie.mp4"> 
</teleport>

video将会被传送到id为popup的元素下。

  • Suspense组件
  • <Suspense> 组件用于协调对组件树中嵌套的异步依赖的处理。

  • 它一般用于包裹多个异步组件处理多个异步组件加载前与完成后的统一状态

  • <Suspense> 组件有两个插槽:#default 和 #fallback,在初始渲染时,<Suspense> 将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起状态等待异步组件加载完毕。在挂起状态期间,展示的是 #fallback插槽内容

nextTick及原理

关于nextTick会问到它的用法,然后是它的原理,然后还可能问到JS的时间循环机制。

问题1:vue中的nextTick是干什么用的?

这个其实比较简单,用过都知道它是干嘛的,vue官方的解释是:

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

这是什么意思呢,其实vue中修改data不会立刻触发dom更新;而是把需要更新的Watcher加入到queueWatcher队列中,然后在合适的时机在nextTick中调用这些Watcher的更新函数进行dom更新,所以在data刚被修改的时候,我们是获取不到更新后的dom的,这时候便需要调用nextTick函数在它的回调函数中获取到变化后的dom

问题2:nextTick原理

  • nextTick原理是借助浏览器事件循环来完成的,因为每次事件循环之间都有一次视图渲染,nextTick尽量在视图渲染之前完成dom更新,所以nextTick优先使用的是promise(微任务)实现

  • 每次执行nextTick时会将传入的回调函数放入一个队列中(callbacks数组),然后当在本次事件循环的同步代码执行完毕后开启一个微任务(promise或者MutationObserver)去依次执行这个callbacks中的回调函数。

  • 但是当浏览器不支持promise的时候在vue2中会进行进行降级处理,依次使用setImmediatesetTimeout开启一个宏任务执行callbacks

  • 当一个data数据更新时对应的watcher便会调用一次nextTick,将它对应的dom更新操作作为回调函数放入callbacks中,所以当我们想获取这个data更新后的dom需要在其值变化后也调用nextTick将回调函数传入排在上个更新dom的回调函数后面,所以我们可以在这个nextTick的回调函数中获取到更新后的data

问题3:js事件循环机制

不属于vue,后面文章再介绍

vue虚拟dom,diff算法

这题在工作中有用吗是???答案是没有用,但是在面试中有用啊,所以我们要会回答?

问题1:什么是虚拟dom?

简单来说就是一个描述dom结构的js对象

问题2:为什么要用虚拟dom?

  • 每当我们用原生JS或者JQ操作DOM时,浏览器会从头开始进行DOM树的构建,频繁的操作DOM开销是很大的。

  • 而虚拟DOM就是为了减少这些操作的,虚拟DOM首先会通过状态生成一个虚拟节点树(js对象),然后使用虚拟节点树进行渲染。当某些状态发生变更时会生成新的虚拟DOM节点树,然后与上一次虚拟DOM节点树进行比较(diff),从而找到差异的部分,最后渲染到真实的DOM节点上面

问题3:说一下diff算法

diff アルゴリズムの本質は、ノードを可能な限り再利用することを目的として、2 つのオブジェクト間の違いを見つけることです。 vueでは、状態が変化した際に、変更後の仮想DOMと変更前の仮想DOMの差分を計算するアルゴリズムです。

具体的な実装については、数文では明確に説明できません。

Vue の両端差分アルゴリズムについて話しましょう - Nuggets (juejin.cn)

という記事をお勧めします。

結論

上記の質問は、基本的に情報を参考にし、私自身の理解を組み合わせてまとめたものですので、多少の間違いや不十分な点があることは避けられません。ぜひご指摘ください。ありがとうございます。

(学習ビデオ共有:

Web フロントエンド開発基本プログラミング ビデオ)

#小道具
#親コンポーネントが子コンポーネントにアクセス
expose&ref

以上が【編集・要約】Vueの面接でよく聞かれる20の質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。