本文小編為大家詳細介紹“Vue有哪些高頻面試題”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“Vue有哪些高頻面試題”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比錦屏網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式錦屏網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋錦屏地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。
這個問題一般問的不多,但是如果問到了你就必須得答出來
回答
Vue2(選項式API) | Vue3(setup) | 描述 |
---|---|---|
beforeCreate | - | 實例創(chuàng)建前 |
created | - | 實例創(chuàng)建后 |
beforeMount | onBeforeMount | DOM掛載前調(diào)用 |
mounted | onMounted | DOM掛載完成調(diào)用 |
beforeUpdate | onBeforeUpdate | 數(shù)據(jù)更新之前被調(diào)用 |
updated | onUpdated | 數(shù)據(jù)更新之后被調(diào)用 |
beforeDestroy | onBeforeUnmount | 組件銷毀前調(diào)用 |
destroyed | onUnmounted | 組件銷毀完成調(diào)用 |
這個相對于上一個問題稍微復雜一點,可以試著理解記憶或者直接記住吧
渲染過程
父beforeCreate
父created
父beforeMount
子beforeCreate
子created
子beforeMount
子mounted
父mounted
更新過程
父beforeUpdate
子beforeUpdate
子updated
父updated
銷毀過程
父beforeDestroy
子beforeDestroy
子destroyed
父destroyed
注意如果子組件是異步組件的話它們的執(zhí)行順序會發(fā)生改變,會先執(zhí)行完父組件的生命周期然后再執(zhí)行子組件的生命周期
這個問題算是非常基本的題了,它也很好理解,面試一般會問這兩個指令的區(qū)別是什么,以及在什么場景下分別用哪個指令合適回答
v-if
表示一個dom元素是否被創(chuàng)建,而v-show
則是控制這個dom元素的display
屬性是否為none
一般在頻繁切換狀態(tài)的地方使用v-show
,v-if
則更適合條件不經(jīng)常改變的場景,因為它切換開銷相對較大
這個問題被問到的頻率還是比較高的,雖然它在實際開發(fā)中并不會這么用。
回答
開發(fā)過程中一般不建議同時將v-for和v-if放在一個標簽中使用
Vue2中v-for的優(yōu)先級會更高,所以會先執(zhí)行循環(huán),再進行v-if判斷,所以這樣就會導致無論需不需展示這個元素,都會先遍歷整個列表
在Vue3中v-if的優(yōu)先級會更高,但是當我們遍歷一個數(shù)組的時候,根據(jù)數(shù)組中的某個元素進行v-if判斷的時候就會報錯,因為v-if會先執(zhí)行此時還沒有拿到這個數(shù)組。所以Vue3中依然不建議這樣使用
computed和watch實際工作中用的比較多,所以問的也比較多,一般理解了基本都能回答上來
computed是計算屬性,當一個屬性受一個或者多個屬性影響的時候可以使用.watch是偵聽器,當我們需要根據(jù)一個屬性的變化而做出一些處理的時候,可以使用watch來對這個屬性進行監(jiān)聽
computed具有緩存的特點,即當它所依賴的屬性發(fā)生改變的時候它才會重新執(zhí)行內(nèi)部邏輯.如下代碼
<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('內(nèi)部邏輯執(zhí)行')
return a.value + b.value
})
</script>
頁面多次使用addSum
,但是只會打印一次"內(nèi)部邏輯執(zhí)行"
watch在頁面首次加載的時候默認不會執(zhí)行,需要設(shè)置immediate:true
首次才會執(zhí)行監(jiān)聽
watch默認只監(jiān)聽一層數(shù)據(jù),不監(jiān)聽多層數(shù)據(jù)里屬性的變化,需要設(shè)置deep:true
才會進行深度監(jiān)聽
關(guān)于vue-router
能問的問題非常多,比如它的實現(xiàn)原理,路由跳轉(zhuǎn),路由守衛(wèi)等等,所以建議去系統(tǒng)的查看vue-router
文檔
問題1:vue-router是什么,描述一下它的原理?
Vue Router是Vue官方的路由管理器,有hash和history兩種模式
hash
模式是通過監(jiān)聽hashchange
事件來實現(xiàn)更新頁面部分內(nèi)容的操作,url后面會帶有#
號
history
模式則是通過監(jiān)聽popstate
事件來實現(xiàn)更新頁面部分內(nèi)容的操作原理和hash
模式差不多,只不過url后面不會出現(xiàn)#
會顯得更加美觀。同時會帶來一個問題,因為沒有#
號,所以當用戶刷新頁面時會向服務(wù)器發(fā)請求導致請求資源為404,因此需要對nginx
進行一個配置,需要把所有路由都重定向到根頁面
問題2:路由跳轉(zhuǎn)方式有哪些?
內(nèi)置組件跳轉(zhuǎn)
router.push({ path: '/home' })
,router.replace({ path: '/home' })
問題3:說一下路由守衛(wèi)?
路由守衛(wèi)分為全局路由守衛(wèi),路由獨享守衛(wèi),組件路由守衛(wèi)
全局路由守衛(wèi)
beforeEach
,接收to、from、next
三個參數(shù),每個路由跳轉(zhuǎn)前都會觸發(fā),登錄驗證時用的比較多
beforeResolve
,和beforeEach
類似,區(qū)別是在導航被確認之前,同時在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后調(diào)用
afterEach,在路由跳轉(zhuǎn)完成后調(diào)用,接收to、from兩個參數(shù)
路由獨享守衛(wèi)
beforeEnter
,一般配置在路由配置文件中(router/index.js),對進入某個路由之前進行相關(guān)操作
組件路由守衛(wèi)
接收
to、from、next
三個參數(shù)
beforeRouteEnter
,進入該組件之前調(diào)用,無法獲取到vue實例
beforeRouteUpdate
,在當前路由改變,但是該組件被復用時調(diào)用
beforeRouteLeave
, 在離開當前組件時調(diào)用
當面試問你會用vue3嗎,如果你回答會用的話,那么大概率會問vue2和vue3有哪些區(qū)別,最近我去面試的時候百分之90都問了這個問題。
回答
寫法上的區(qū)別:vue2使用的是options(選項)Api
,vue3的是composition Api
(當然vue3也兼容composition api
)。options Api
中methods,compute,data
等api都是分散的。而composition api
中的代碼是根據(jù)邏輯功能來組織的,我們可以將一個功能所定義的methods,compute,data
等api會放在一起,讓我們可以更靈活地組合組件邏輯。
vue2將響應式數(shù)據(jù)放到data函數(shù)中,而vue3則是使用ref
和reactive
將數(shù)據(jù)聲明為響應式
響應式實現(xiàn)方式:vue2中是通過Object.defineProperty
對數(shù)據(jù)劫持實現(xiàn)的,vue3中則是使用Proxy
對數(shù)據(jù)代理實現(xiàn)的。
生命周期區(qū)別:vue3中將beforeCreate
和created
合并到了setup
函數(shù)中
根節(jié)點: vue3組件允許多個根節(jié)點,而vue2只允許一個
內(nèi)置組件: vue3新增了傳送組件Teleport
和異步依賴處理組件Suspense
面試一般會問你如何寫一個vue插件,所以沒寫過vue插件的最好去親自體驗一下
回答:
vue
實例會有一個use
函數(shù),它接受的是一個帶有install
函數(shù)的對象和一個可選的選項對象,當我們使用 vue.use(plugin)
或者app.use(plugin)
會調(diào)用我們插件的install
屬性的函數(shù),并且將當前組件的實例傳進來.所以在插件中就可以對這個實例進行一些操作來實現(xiàn)我們插件的功能
插槽slot
可以理解為占坑,當使用一個組件的時候,在組件標簽里的對應的內(nèi)容就會替換掉這個組件中的slot
標簽。
插槽分為默認插槽
,具名插槽
,作用域插槽
。
默認插槽子組件中用slot
標簽來確定渲染位置,父組件使用它時直接在子組件的標簽內(nèi)寫入內(nèi)容即可
//子組件
<template>
<slot />
</template>
//父組件
<Child>
<div>默認插槽</div>
</Child>
具名插槽
顧名思義就是具有名字的插槽,子組件中可以用name
熟悉對slot
命名,父組件在使用的時候通過template
中的v-slot:name
或者#name
來定義這個插槽中的內(nèi)容
//子組件
<template>
<slot name="content"></slot>
</template>
//父組件
<Child>
<template v-slot:content>具名插槽內(nèi)容</template>
</Child>
作用域插槽
子組件中的slot
可以通過類似組件屬性傳遞的方式將子組件的值傳遞給父組件中這個子組件的插槽內(nèi)容中
(子組件標簽內(nèi)),在父組件使用子組件的時候要用v-slot
的值進行接收這些參數(shù),默認插槽可以將其直接寫在子組件標簽上,具名插槽則寫在template
上。而傳過來的值只能在子組件標簽中或者template
標簽中使用。所以在父組件作用域中獲取到了子組件作用域中的變量,可以認為作用域插槽延伸了子組件數(shù)據(jù)的作用范圍,因此叫做作用域插槽
如果你想詳細理解插槽的作用可以閱讀這篇文章Vue3中插槽(slot)用法匯總 - 掘金 (juejin.cn)
這里我大概歸納了一下vue2和vue3的傳參方式
方式 | Vue2 | Vue3 |
---|---|---|
父傳子 | props | props |
子傳父 | $emit | emits |
父傳子 | $attrs | attrs |
子傳父 | $listeners | 無(合并到 attrs方式) |
父傳子 | provide/inject | provide/inject |
子組件訪問父組件 | $parent | 無 |
父組件訪問子組件 | $children | 無 |
父組件訪問子組件 | $ref | expose&ref |
兄弟組件傳值 | EventBus | mitt |
它們的具體用法可以參考我的這篇文章盤點Vue2和Vue3的10種組件通信方式(值得收藏) - 掘金 (juejin.cn)
除了上面的傳參方式你也可以回答Vuex和Pinia,前提你了解這兩個狀態(tài)管理器,因為你說了大概率下個問題就會問你Vuex和Pinia
面試問到這個問題的時候,不要上來就開始說什么state
,mutation
...。你要先闡述Vuex干嘛用的,什么時候需要用Vuex。
回答
Vuex是Vue中的全局狀態(tài)管理框架,它可以管理應用的所有組件的狀態(tài)。并不是每個項目都需要引入Vuex的,當我們的項目有很多個頁面,并且這些頁面共享著多個數(shù)據(jù)狀態(tài),此時我們可以引入Vuex。
Vuex有三個核心的概念,state
,mutations
,actions
,其中state
為存放數(shù)據(jù)的地方,mutations
中的函數(shù)作用則是用來修改state
,actions
中一般是用了處理一些異步操作的函數(shù)。
Vuex除了上面三個概念還有getters
,moudles
,getters
就像Vue中的計算屬性computed
一樣用來描述依賴響應式狀態(tài)state中的復雜邏輯。moudles
則是可以將store分割成模塊(module),每個模塊都擁有自己的state
,mutations
,actions
等,在大型應用中經(jīng)常用到
場景:當我們異步獲取結(jié)果并賦值給state的時候,比如數(shù)據(jù)請求,我們可以在actions
中進行數(shù)據(jù)請求,拿到結(jié)果通過它的dispatch
方法調(diào)用mutations
中修改state
的函數(shù),從而將結(jié)果賦值給了state
這個現(xiàn)在問的好像不多,從我最近面試來看只有我提到了才會問一下,但是以后問的肯定會越來越多。關(guān)于pinia問的一般是它和Vuex的區(qū)別,確切的說應該是它和Vuex4之間的區(qū)別
回答
pinia
其實就是Vuex5,它和Vuex的主要區(qū)別有以下幾點
Pinia使用更簡單,更符合開發(fā)者的開發(fā)習慣
pinia
中沒有了mutations
,狀態(tài)state
的修改可以直接進行修改,或者在actions
中修改,或者使用它的$patch
方法進行修改
pinia
中沒有了modules
,如果想使用多個store,直接使用defineStore
定義多個store傳入不同的id即可
更好的TS支持,不需要創(chuàng)建自定義的復雜包裝器來支持TS
vue 官方提供了v-text、v-for、v-model、v-if 等常用的指令。除此之外vue 還允許開發(fā)者自定義指令。面試經(jīng)常會問什么是自定義指令?你用自定義指令做過哪些功能?
回答1:什么是自定義指令?
自定義指令包含局部指令和全局指令,在模板中使用指令前必須先使用directives
選項注冊。局部指令指在某個組件中注冊,而全局則是將指令注冊到全局,通常在main.js中注冊。
自定義指令由一個包含類似組件生命周期鉤子的對象來定義。它的生命周期鉤子包含created
,beforeMount
,mounted
,beforeUpdate
,updated
,beforeUnmount
,unmounted
,
常用的鉤子為mounted
和 updated
,它接受el
,binding
等參數(shù).binding
參數(shù)的值一般包含綁定到這個元素上的信息,比如下面這個指令
<div v-example:foo.bar="baz">
它的binding會是這個對象
{
arg: 'foo',
modifiers: { bar: true },
value: /* `baz` 的值 */,
oldValue: /* 上一次更新時 `baz` 的值 */
}
回答2:你用自定義指令做過哪些功能?
數(shù)據(jù)埋點,通過綁定自定義事件傳入點擊當前元素需要埋點的事件名,在指令中監(jiān)聽當前元素的點擊事件后調(diào)用后臺接口將事件名傳入
權(quán)限控制,通過綁定自定義事件傳入控制當前元素的權(quán)限字段,在指令中獲取到當前元素根據(jù)權(quán)限字段來控制該元素的狀態(tài)(顯示,隱藏等)
...
官網(wǎng)描述
<KeepAlive>
是一個內(nèi)置組件,它的功能是在多個組件間動態(tài)切換時緩存被移除的組件實例。
回答
通常我們切換組件的時候,上一個組件就會被銷毀,而當我們使用<KeepAlive>
將其包裹的話這個組件就會被緩存,當這個組件再一次被顯示時就會保留之前的狀態(tài)。
keep-alive
接收兩個屬性include
和 exclude
,分別代表哪些組件要用緩存和哪些不需要緩存,它接收組件的名字數(shù)組,字符串或者正則,當我們使用動態(tài)組件component
或者路由router-view
的時候可以使用
keep-alive
還接收max
屬性表示最大緩存實例數(shù),如果超出這個數(shù)則最久沒有被訪問的緩存實例將被銷毀。
keep-alive
有兩個生命周期,分別是activated
和deactivated
,activated
鉤子會在首次掛載或者每次從緩存中被重新插入的時候調(diào)用。deactivated
鉤子則是在組件從DOM上移除或者組件卸載時調(diào)用
vue3中已經(jīng)沒有Mixin
這個概念了,所以未來被問到的幾率會越來越小,但是目前被問到的頻率還是很高的。一般會它的概念以及優(yōu)缺點,有時還會問它與父組件的生命周期執(zhí)行順序
vue官網(wǎng)描述:
混入 (mixin) 提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復用功能。一個混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項。
回答1.Mixin
的作用將組件的公共邏輯提取出來,哪個組件需要用到時,直接將提取的這部分混入到組件內(nèi)部即可
2. Mixin
的生命周期會在父組件生命周期之前執(zhí)行,如果Mixin
中的屬性或者方法與父組件沖突則會使用父組件中的
2. 優(yōu)點:可以降低代碼冗余提高邏輯復用性。
3. 缺點:命名容易沖突,不好追溯源,后期排查不方便
這道題問道的頻率極高,就我經(jīng)歷的多場面試幾乎都會問到,而且是面試到vue方面的開門題。
下面是我自己的理解回答,以vue2為例,大家可以借鑒參考
vue的響應式原理是根據(jù)Object.defineProperty
這個api來對數(shù)據(jù)進行劫持并結(jié)合發(fā)布者-訂閱者模式實現(xiàn)的
首先會利用Object.defineProperty
中的get
函數(shù)來對vue中的data的所有屬性進行訪問劫持,中間會涉及到劫持data中更深層次的屬性需要遞歸調(diào)用劫持方法。這里是通過一個Observer
類實現(xiàn)的
劫持到每一個屬性后會給這個屬性綁定多個訂閱者watcher
,因為一個屬性可能被用在很多地方;而這個watcher
中則包含更新視圖的函數(shù)update
。
watcher
和屬性的對應關(guān)系以及和視圖的聯(lián)系則是通過編譯模板Compile
類來實現(xiàn)的。Compile
中會拿到整個dom對象,然后遍歷元素子節(jié)點獲取到使用過vue中data屬性的則給該屬性直接添加一個watcher
并賦予一些更新當前視圖的方法.
每個屬性的多個訂閱者watcher
都會被添加到對應的數(shù)組中,這里則是通過Deps
類實現(xiàn)的,初始化watcher
的時候會調(diào)用Deps
中的addSub
方法將對應watcher
添加該類的Subs
數(shù)組中
當data中的某個屬性發(fā)生改變時則會觸發(fā)Object.defineProperty
中的set
函數(shù),這時便會調(diào)用該屬性的Deps
類中的notify
函數(shù)遍歷Subs
數(shù)組中的訂閱者watcher
并調(diào)用其函數(shù)update
去觸發(fā)視圖的更新
一般問完響應式原理可能會問這兩者的區(qū)別
回答
Object.defineProperty
只能代理屬性,Proxy
代理的是對象。
對象上新增屬性,Proxy
可以監(jiān)聽到,Object.defineProperty
不能。
Object.defineProperty
的代理行為是在破壞原對象的基礎(chǔ)上實現(xiàn)的,Proxy 則不會破壞原對象,只是在原對象上覆蓋了一層。
數(shù)組新增修改,Proxy
可以監(jiān)聽到,Object.defineProperty
不能。
Proxy
不兼容IE11
及以下
vue3新增了兩個內(nèi)置組件分別是Teleport
和Suspense
。
Teleport
組件
可以稱之為傳送門,作用將其插槽內(nèi)容渲染到 DOM 中的另一個位置,接收兩個參數(shù)to(要去的位置)和disabled(是否留在原位置)。接收比如下面代碼
<teleport to="#popup">
<video src="./my-movie.mp4">
</teleport>
video將會被傳送到id為popup的元素下。
Suspense
組件
<Suspense>
組件用于協(xié)調(diào)對組件樹中嵌套的異步依賴的處理。
它一般用于包裹多個異步組件處理多個異步組件加載前與完成后的統(tǒng)一狀態(tài)
<Suspense>
組件有兩個插槽:#default
和 #fallback
,在初始渲染時,<Suspense>
將在內(nèi)存中渲染其默認的插槽內(nèi)容。如果在這個過程中遇到任何異步依賴,則會進入掛起狀態(tài)等待異步組件加載完畢。在掛起狀態(tài)期間,展示的是 #fallback
插槽內(nèi)容
關(guān)于nextTick會問到它的用法,然后是它的原理,然后還可能問到JS的時間循環(huán)機制。
問題1:vue中的nextTick是干什么用的?
這個其實比較簡單,用過都知道它是干嘛的,vue官方的解釋是:
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM。
這是什么意思呢,其實vue中修改data不會立刻觸發(fā)dom更新;而是把需要更新的Watcher加入到queueWatcher隊列中,然后在合適的時機在nextTick中調(diào)用這些Watcher的更新函數(shù)進行dom更新,所以在data剛被修改的時候,我們是獲取不到更新后的dom的,這時候便需要調(diào)用nextTick函數(shù)在它的回調(diào)函數(shù)中獲取到變化后的dom
問題2:nextTick原理
nextTick原理是借助瀏覽器事件循環(huán)來完成的,因為每次事件循環(huán)之間都有一次視圖渲染,nextTick盡量在視圖渲染之前完成dom更新,所以nextTick優(yōu)先使用的是promise(微任務(wù))實現(xiàn)
每次執(zhí)行nextTick時會將傳入的回調(diào)函數(shù)放入一個隊列中(callbacks數(shù)組),然后當在本次事件循環(huán)的同步代碼執(zhí)行完畢后開啟一個微任務(wù)(promise或者MutationObserver)去依次執(zhí)行這個callbacks中的回調(diào)函數(shù)。
但是當瀏覽器不支持promise的時候在vue2中會進行進行降級處理,依次使用setImmediate
、setTimeout
開啟一個宏任務(wù)執(zhí)行callbacks
當一個data數(shù)據(jù)更新時對應的watcher便會調(diào)用一次nextTick,將它對應的dom更新操作作為回調(diào)函數(shù)放入callbacks中,所以當我們想獲取這個data更新后的dom需要在其值變化后也調(diào)用nextTick將回調(diào)函數(shù)傳入排在上個更新dom的回調(diào)函數(shù)后面,所以我們可以在這個nextTick的回調(diào)函數(shù)中獲取到更新后的data
這題在工作中有用嗎是???答案是沒有用,但是在面試中有用啊,所以我們要會回答?
問題1:什么是虛擬dom?
簡單來說就是一個描述dom結(jié)構(gòu)的js對象
問題2:為什么要用虛擬dom?
每當我們用原生JS或者JQ操作DOM
時,瀏覽器會從頭開始進行DOM
樹的構(gòu)建,頻繁的操作DOM
開銷是很大的。
而虛擬DOM
就是為了減少這些操作的,虛擬DOM
首先會通過狀態(tài)生成一個虛擬節(jié)點樹(js對象),然后使用虛擬節(jié)點樹進行渲染。當某些狀態(tài)發(fā)生變更時會生成新的虛擬DOM節(jié)點樹,然后與上一次虛擬DOM節(jié)點樹進行比較(diff),從而找到差異的部分,最后渲染到真實的DOM節(jié)點上面
問題3:說一下diff算法
diff算法的本質(zhì)是找出兩個對象之間的差異,目的是盡可能復用節(jié)點。在vue中是當狀態(tài)發(fā)生改變,用來計算改變后的虛擬DOM與改變前的虛擬DOM之間的差異的算法。
讀到這里,這篇“Vue有哪些高頻面試題”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當前標題:Vue有哪些高頻面試題
文章源于:http://m.newbst.com/article12/jheogc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、做網(wǎng)站、App設(shè)計、網(wǎng)站導航、網(wǎng)站設(shè)計公司、手機網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)