小編給大家分享一下Vue必備面試題有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
前言
Vue框架部分我們會涉及一些高頻且有一定探討價值的面試題,我們不會涉及一些非常初級的在官方文檔就能查看的純記憶性質的面試題,比如:
vue常用的修飾符?
vue-cli 工程常用的 npm 命令有哪些?
vue中 keep-alive 組件的作用?
首先,上述類型的面試題在文檔中可查,沒有比官方文檔更權威的答案了,其次這種問題沒有太大價值,除了考察候選人的記憶力,最后,這種面試題只要用過vue的都知道,沒有必要占用我們的篇幅.
我們的問題并不多,但是難度可能會高一些,如果你真的搞懂了這些問題,在絕大多數情況下會有舉一反三的效果,可以說基本能拿下Vue相關的所有重要知識點了.
你對MVVM的理解?
MVVM是什么?
MVVM 模式,顧名思義即 Model-View-ViewModel 模式。它萌芽于2005年微軟推出的基于 Windows 的用戶界面框架 WPF ,前端最早的 MVVM 框架 knockout 在2010年發布。
Model 層: 對應數據層的域模型,它主要做域模型的同步。通過 Ajax/fetch 等 API 完成客戶端和服務端業務 Model 的同步。在層間關系里,它主要用于抽象出 ViewModel 中視圖的 Model。
View 層:作為視圖模板存在,在 MVVM 里,整個 View 是一個動態模板。除了定義結構、布局外,它展示的是 ViewModel 層的數據和狀態。View 層不負責處理狀態,View 層做的是 數據綁定的聲明、 指令的聲明、 事件綁定的聲明。
ViewModel 層:把 View 需要的層數據暴露,并對 View 層的 數據綁定聲明、 指令聲明、 事件綁定聲明 負責,也就是處理 View 層的具體業務邏輯。ViewModel 底層會做好綁定屬性的監聽。當 ViewModel 中數據變化,View 層會得到更新;而當 View 中聲明了數據的雙向綁定(通常是表單元素),框架也會監聽 View 層(表單)值的變化。一旦值變化,View 層綁定的 ViewModel 中的數據也會得到自動更新。

MVVM的優缺點?
優點:
分離視圖(View)和模型(Model),降低代碼耦合,提高視圖或者邏輯的重用性: 比如視圖(View)可以獨立于Model變化和修改,一個ViewModel可以綁定不同的"View"上,當View變化的時候Model不可以不變,當Model變化的時候View也可以不變。你可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯
提高可測試性: ViewModel的存在可以幫助開發者更好地編寫測試代碼
自動更新dom: 利用雙向綁定,數據更新后視圖自動更新,讓開發者從繁瑣的手動dom中解放
缺點:
Bug很難被調試: 因為使用雙向綁定的模式,當你看到界面異常了,有可能是你View的代碼有Bug,也可能是Model的代碼有問題。數據綁定使得一個位置的Bug被快速傳遞到別的位置,要定位原始出問題的地方就變得不那么容易了。另外,數據綁定的聲明是指令式地寫在View的模版當中的,這些內容是沒辦法去打斷點debug的
一個大的模塊中model也會很大,雖然使用方便了也很容易保證了數據的一致性,當時長期持有,不釋放內存就造成了花費更多的內存
對于大型的圖形應用程序,視圖狀態較多,ViewModel的構建和維護的成本都會比較高
你對Vue生命周期的理解?
生命周期是什么
Vue 實例有一個完整的生命周期,也就是從開始創建、初始化數據、編譯模版、掛載Dom -> 渲染、更新 -> 渲染、卸載等一系列過程,我們稱這是Vue的生命周期。
各個生命周期的作用
生命周期 描述 beforeCreate 組件實例被創建之初,組件的屬性生效之前 created 組件實例已經完全創建,屬性也綁定,但真實dom還沒有生成,$el還不可用 beforeMount 在掛載開始之前被調用:相關的 render 函數首次被調用 mounted el 被新創建的 vm.$el 替換,并掛載到實例上去之后調用該鉤子 beforeUpdate 組件數據更新之前調用,發生在虛擬 DOM 打補丁之前 update 組件數據更新之后 activited keep-alive專屬,組件被激活時調用 deadctivated keep-alive專屬,組件被銷毀時調用 beforeDestory 組件銷毀前調用 destoryed 組件銷毀后調用 生命周期示意圖

異步請求適合在哪個生命周期調用?
官方實例的異步請求是在mounted生命周期中調用的,而實際上也可以在created生命周期中調用。
Vue組件如何通信?
Vue組件通信的方法如下:
props/$emit+v-on: 通過props將數據自上而下傳遞,而通過$emit和v-on來向上傳遞信息。
EventBus: 通過EventBus進行信息的發布與訂閱
vuex: 是全局數據管理庫,可以通過vuex管理全局的數據流
$attrs/$listeners: Vue2.4中加入的$attrs/$listeners可以進行跨級的組件通信
provide/inject:以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效,這成為了跨組件通信的基礎
還有一些用solt插槽或者ref實例進行通信的,使用場景過于有限就不贅述了。
computed和watch有什么區別?
computed:
computed是計算屬性,也就是計算值,它更多用于計算值的場景
computed具有緩存性,computed的值在getter執行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調用對應的getter來計算
computed適用于計算比較消耗性能的計算場景
watch:
更多的是「觀察」的作用,類似于某些數據的監聽回調,用于觀察props $emit或者本組件的值,當數據變化時來執行回調進行后續操作
無緩存性,頁面重新渲染時值不變化也會執行
小結:
當我們要進行數值計算,而且依賴于其他數據,那么把這個數據設計為computed
如果你需要在某個數據變化時做一些事情,使用watch來觀察這個數據變化
Vue是如何實現雙向綁定的?
利用Object.defineProperty劫持對象的訪問器,在屬性值發生變化時我們可以獲取變化,然后根據變化進行后續響應,在vue3.0中通過Proxy代理對象進行類似的操作。
// 這是將要被劫持的對象
const data = {
name: '',
};
function say(name) {
if (name === '古天樂') {
console.log('給大家推薦一款超好玩的游戲');
} else if (name === '渣渣輝') {
console.log('戲我演過很多,可游戲我只玩貪玩懶月');
} else {
console.log('來做我的兄弟');
}
}
// 遍歷對象,對其屬性值進行劫持
Object.keys(data).forEach(function(key) {
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
console.log('get');
},
set: function(newVal) {
// 當屬性值發生變化時我們可以進行額外操作
console.log(`大家好,我系${newVal}`);
say(newVal);
},
});
});
data.name = '渣渣輝';
//大家好,我系渣渣輝
//戲我演過很多,可游戲我只玩貪玩懶月
復制代碼詳細實現見Proxy比defineproperty優劣對比?
Proxy與Object.defineProperty的優劣對比?
Proxy的優勢如下:
Proxy可以直接監聽對象而非屬性
Proxy可以直接監聽數組的變化
Proxy有多達13種攔截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具備的
Proxy返回的是一個新對象,我們可以只操作新的對象達到目的,而Object.defineProperty只能遍歷對象屬性直接修改
Proxy作為新標準將受到瀏覽器廠商重點持續的性能優化,也就是傳說中的新標準的性能紅利
Object.defineProperty的優勢如下:
兼容性好,支持IE9
詳細實現見Proxy比defineproperty優劣對比?
你是如何理解Vue的響應式系統的?

響應式系統簡述:
任何一個 Vue Component 都有一個與之對應的 Watcher 實例。
Vue 的 data 上的屬性會被添加 getter 和 setter 屬性。
當 Vue Component render 函數被執行的時候, data 上會被 觸碰(touch), 即被讀, getter 方法會被調用, 此時 Vue 會去記錄此 Vue component 所依賴的所有 data。(這一過程被稱為依賴收集)
data 被改動時(主要是用戶操作), 即被寫, setter 方法會被調用, 此時 Vue 會去通知所有依賴于此 data 的組件去調用他們的 render 函數進行更新。
虛擬DOM的優劣如何?
優點:
保證性能下限: 虛擬DOM可以經過diff找出最小差異,然后批量進行patch,這種操作雖然比不上手動優化,但是比起粗暴的DOM操作性能要好很多,因此虛擬DOM可以保證性能下限
無需手動操作DOM: 虛擬DOM的diff和patch都是在一次更新中自動進行的,我們無需手動操作DOM,極大提高開發效率
跨平臺: 虛擬DOM本質上是JavaScript對象,而DOM與平臺強相關,相比之下虛擬DOM可以進行更方便地跨平臺操作,例如服務器渲染、移動端開發等等
缺點:
無法進行極致優化: 在一些性能要求極高的應用中虛擬DOM無法進行針對性的極致優化,比如VScode采用直接手動操作DOM的方式進行極端的性能優化
虛擬DOM實現原理?
虛擬DOM本質上是JavaScript對象,是對真實DOM的抽象
狀態變更時,記錄新樹和舊樹的差異
最后把差異更新到真正的dom中
詳細實現見虛擬DOM原理?
既然Vue通過數據劫持可以精準探測數據變化,為什么還需要虛擬DOM進行diff檢測差異?
考點: Vue的變化偵測原理
前置知識: 依賴收集、虛擬DOM、響應式系統
現代前端框架有兩種方式偵測變化,一種是pull一種是push
pull: 其代表為React,我們可以回憶一下React是如何偵測到變化的,我們通常會用setStateAPI顯式更新,然后React會進行一層層的Virtual Dom Diff操作找出差異,然后Patch到DOM上,React從一開始就不知道到底是哪發生了變化,只是知道「有變化了」,然后再進行比較暴力的Diff操作查找「哪發生變化了」,另外一個代表就是Angular的臟檢查操作。
push: Vue的響應式系統則是push的代表,當Vue程序初始化的時候就會對數據data進行依賴的收集,一但數據發生變化,響應式系統就會立刻得知,因此Vue是一開始就知道是「在哪發生變化了」,但是這又會產生一個問題,如果你熟悉Vue的響應式系統就知道,通常一個綁定一個數據就需要一個Watcher,一但我們的綁定細粒度過高就會產生大量的Watcher,這會帶來內存以及依賴追蹤的開銷,而細粒度過低會無法精準偵測變化,因此Vue的設計是選擇中等細粒度的方案,在組件級別進行push偵測的方式,也就是那套響應式系統,通常我們會第一時間偵測到發生變化的組件,然后在組件內部進行Virtual Dom Diff獲取更加具體的差異,而Virtual Dom Diff則是pull操作,Vue是push+pull結合的方式進行變化偵測的.
Vue為什么沒有類似于React中shouldComponentUpdate的生命周期?
考點: Vue的變化偵測原理
前置知識: 依賴收集、虛擬DOM、響應式系統
根本原因是Vue與React的變化偵測方式有所不同
React是pull的方式偵測變化,當React知道發生變化后,會使用Virtual Dom Diff進行差異檢測,但是很多組件實際上是肯定不會發生變化的,這個時候需要用shouldComponentUpdate進行手動操作來減少diff,從而提高程序整體的性能.
Vue是pull+push的方式偵測變化的,在一開始就知道那個組件發生了變化,因此在push的階段并不需要手動控制diff,而組件內部采用的diff方式實際上是可以引入類似于shouldComponentUpdate相關生命周期的,但是通常合理大小的組件不會有過量的diff,手動優化的價值有限,因此目前Vue并沒有考慮引入shouldComponentUpdate這種手動優化的生命周期.
Vue中的key到底有什么用?
key是為Vue中的vnode標記的唯一id,通過這個key,我們的diff操作可以更準確、更快速
diff算法的過程中,先會進行新舊節點的首尾交叉對比,當無法匹配的時候會用新節點的key與舊節點進行比對,然后超出差異.
diff程可以概括為:oldCh和newCh各有兩個頭尾的變量StartIdx和EndIdx,它們的2個變量相互比較,一共有4種比較方式。如果4種比較都沒匹配,如果設置了key,就會用key進行比較,在比較的過程中,變量會往中間靠,一旦StartIdx>EndIdx表明oldCh和newCh至少有一個已經遍歷完了,就會結束比較,這四種比較方式就是首、尾、舊尾新頭、舊頭新尾.
準確: 如果不加key,那么vue會選擇復用節點(Vue的就地更新策略),導致之前節點的狀態被保留下來,會產生一系列的bug.
快速: key的唯一性可以被Map數據結構充分利用,相比于遍歷查找的時間復雜度O(n),Map的時間復雜度僅僅為O(1).

以上是“Vue必備面試題有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。