本篇文章給大家總結分享37個常見Vue面試題,帶你鞏固一波地基,增強你的Vue知識儲備,背就完事了!相關推薦:
一、談談你對MVVM的理解?
對映關係簡化,隱藏controller
MVVM在MVC的基礎上,把控制層隱藏掉了。
Vue不是一個MVVM框架,它是一個檢視層框架。【相關推薦:】
ViewModal是一個橋樑,將資料和檢視進行關聯。
二、談談你對Vue中響應式資料的理解?
陣列和物件型別的值變化的時候,通過defineReactive
方法,藉助了defineProperty
,將所有的屬性新增了getter
和setter
。使用者在取值和設定的時候,可以進行一些操作。
缺陷:只能監控最外層的屬性,如果是多層的,就要進行全量遞迴。
get裡面會做依賴蒐集(dep[watcher, watcher])
set裡面會做資料更新(notify,通知watcher更新)
三、Vue中如何檢測陣列的變化?
vue中對陣列沒有進行defineProperty,而是重寫了陣列的7個方法。
分別是:
- push
- shift
- pop
- splice
- unshift
- sort
- reverse
因為這些方法都會改變陣列本身。
陣列裡的索引和長度是無法被監控的。
四、Vue中如何進行依賴收集的?
Vue初始化的時候,掛載之後會進行編譯。生成renderFunction。
當取值的時候,就會蒐集watcher,放到dep裡面。
當使用者更改值的時候,就會通知watcher,去更新檢視。
五、如何理解Vue中的模板編譯原理?
這個問題的核心是如何將template轉換成render函數。
- 將template模組轉換成ast語法書 - parserHTML
- 對靜態語法做標記(某些節點不改變)
- 重新生成程式碼 - codeGen,使用with語法包裹字串
六、Vue生命週期勾點是如何實現的?
Vue的生命週期勾點是回撥函數,當建立元件範例的過程中會呼叫相應的勾點方法。
內部會對勾點進行處理,將勾點函數維護成陣列的形式。
七、Vue元件生命週期有哪些?
- beforeCreate 在範例初始化之後,資料觀測observer 和event、watcher事件設定之前被呼叫
- created 範例已經建立完成,在這一步,以下設定被完成
- 資料觀測
- 屬性和方法的運算
- watch/event時間回撥
- $el尚未生成
- beforeMount 在掛載之前被呼叫,render尚未被呼叫
- mounted el被新建立的vm.$el替換,並掛載到範例上去之後呼叫
- beforeUpdate 資料更新時,被呼叫,發生在虛擬Dom重新渲染和打修補程式之前
- update 由於資料更改導致的虛擬Dom重新渲染和打修補程式,在這之後呼叫
- beforeDestroy 範例銷燬之前呼叫
- destroyed 範例銷燬之後呼叫,呼叫後Vue範例的所有東西都會被解綁,所有的事件監聽會被移除,子範例被銷燬,該勾點在伺服器端渲染期間不被呼叫
- keep-alive(activated & deactivated)
八、vue.mixin的使用場景和原理?
Vue的mixin的作用就是抽離公共的業務邏輯,原理類似物件的繼承,當元件初始化的時候,會呼叫mergeOptions方法進行合併,採用策略模式針對不同的屬性進行合併。
如果混入的資料和本身元件的資料有衝突,採用本身的資料為準。
缺點:命名衝突、資料來源不清晰
九、Vue的元件data為什麼必須是一個函數?
new Vue
是一個單例模式,不會有任何的合併操作,所以根範例不必校驗data一定是一個函數。
元件的data必須是一個函數,是為了防止兩個元件的資料產生汙染。
如果都是物件的話,會在合併的時候,指向同一個地址。
而如果是函數的時候,合併的時候呼叫,會產生兩個空間。
十、請說明nextTick的原理。
nextTick是一個微任務。
- nextTick中的回撥是在下次Dom更新迴圈結束之後執行的延遲迴撥
- 可以用於獲取更新後的Dom
- Vue中的資料更新是非同步的,使用nextTick可以保證使用者定義的邏輯在更新之後執行
十一、computed和watch的區別是什麼?
- computed和watch都基於watcher來實現的。
- computed的屬性是具備快取的,依賴的值不發生變化,對其取值時計算屬性方法不會重複執行
- watch是監控值的變化,當值發生改變的時候,會呼叫回撥函數
十二、Vue.set方法是如何實現的?
- vue給物件和陣列本身都增加了dep屬性
- 當給物件新增不存在的屬性的時候,就會觸發物件依賴的watcher去更新
- 當修改陣列索引的時候,就呼叫陣列本身的splice方法去更新陣列
十三、Vue為什麼要用虛擬Dom
- 虛擬dom就是用js物件來描述真實Dom,是對真實Dom的抽象
- 由於直接操作Dom效能低,但是js層的操作效率高,可以將Dom操作轉化成物件操作。最終通過diff演演算法比對差異進行更新Dom
- 虛擬Dom不依賴真實平臺環境,可以實現跨平臺
十四、Vue的diff演演算法原理是什麼?
Vue的diff演演算法是平級比較,不考慮跨級比較的情況。內部採用深度遞迴的方式+雙指標方式比較
- 先比較兩個節點是不是相同節點
- 相同節點比較屬性,複用老節點
- 先比較兒子節點,考慮老節點和新節點兒子的情況
- 優化比較:頭頭、尾尾、頭尾、尾頭
- 比對查詢,進行復用
十五、既然vue通過資料劫持可以精準的探測資料變化,為什麼還要進行diff檢測差異?
- 響應式資料變化,Vue確實可以在資料變化的時候,響應式系統可以立刻得知。但是如何每個屬性都新增watcher的話,效能會非常的差。
- 粒度過細,會導致更新不精準
所以採用watcher + Diff演演算法來檢測差異。
十六、請說明key的作用和原理
- Vue在patch過程中,通過key可以判斷兩個虛擬節點是否是相同節點。
- 沒有key會導致更新的時候出問題
- 儘量不要採用索引作為key
十七、談談對元件的理解
- 元件化開發能大幅提高應用開發效率、測試性、複用性
- 常用的元件化技術:屬性、自定義事件、插槽
- 降低更新範圍,值重新渲染變化的元件
- 高內聚、低耦合、單向資料流
十八、請描述元件的渲染流程
產生元件虛擬節點 -> 建立元件的真實節點 -> 插入到頁面
十九、請描述元件的更新流程
屬性更新會觸發patchVnode方法,元件的虛擬節點會呼叫prepatch勾點,然後更新屬性,更新元件。
二十、非同步元件原理
先渲染非同步預留位置節點 -> 元件載入完畢後呼叫forceUpdate強制更新。
二十一、函陣列件的優勢和原理
- 函數式元件的特性:無狀態、無生命週期、無this。因此效能會高一點。
正常的一個元件是一個類繼承了Vue。
函數式元件,就是一個普通的函數。
二十二、元件的傳值方式有哪些?
- props和emit:父組件向子組件傳遞數據,通過prop傳遞。子組件傳遞數據給父組件是通過emit事件
- parent,children獲取當前元件的父元件和當前元件的子元件
- attrs和listeners 。
- 父元件通過provide提供,子元件通過inject注入變數
- $ref獲取範例
- eventBus平級元件資料傳遞
- Vuex
二十三、$attrs是為了解決什麼問題出現的?
主要作用是為了實現批次傳遞資料。
provide/inject更適合應用在外掛中,主要實現跨級資料傳遞。
二十四、v-for和v-if哪個優先順序更高?
首先,v-for和v-if 不能在同一個標籤中使用。
先處理v-for,再處理v-if。
如果同時遇到的時候,應該考慮先用計算屬性處理資料,在進行v-for,可以減少迴圈次數。
二十五、v-mode是如何實現的?
在元件上用的v-model,是model和callback
在普通元素上用v-model,會生成指令,還可能因為不同的元素:
- 生成value和input
- 生成change和radio
- 生成change和checked
指令在什麼時候會呼叫?
原始碼:
二十六、Vue的普通Slot以及作用域Slot的區別
普通插槽
普通插槽是渲染後做替換的工作。父元件渲染完畢後,替換子元件的內容。
在模板編譯的時候,處理元件中的子節點和slot標籤
在建立元素的時候,用_t()方法方法來替換_v()的內容。
作用域插槽
作用域插槽可以拿到子元件裡面的屬性。在子元件中傳入屬性然後渲染。
作用域插槽的編譯結果:
二十八、Vue.use是幹什麼的?
Vue.use
是用來使用外掛的。我們可以在外掛中擴充套件全域性元件、指令、原型方法等。
會呼叫install
方法將Vue的構建函數預設傳入,在外掛中可以使用vue,無需依賴vue庫
二十九、元件寫name有啥好處?
- 增加name屬性,會在components屬性中增加元件本身,實現元件的遞迴呼叫。
- 可以表示元件的具體名稱,方便偵錯和查詢對應的元件。
三十、vue的修飾符有哪些?
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
- .right
- .center
- .middle
- .alt
三十一、如何理解自定義指令?
- 在生成ast語法樹時,遇到指令會給當前元素新增directives屬性
- 通過genDirectives生成指令程式碼
- 在patch前,將指令的勾點提取到cbs中,在patch過程中呼叫對應的勾點
- 當執行cbs對應的勾點時,呼叫對應指令定義方法
三十二、keep-alive平時在哪裡使用?原理是什麼?
- 使用keep-alive包裹動態元件時,會對元件進行快取,避免元件重新建立
使用有兩個場景,一個是動態元件,一個是router-view
這裡建立了一個白名單和一個黑名單。表明哪些需要需要做快取,哪些不需要做快取。以及最大的快取個數。
快取的是元件的範例,用key和value物件儲存。
載入的時候,監控include和exclude。
如果不需要快取,直接返回虛擬節點。
如果需要快取,就用元件的id和標籤名,生成一個key,把當前vnode的instance作為value,存成一個物件。這就是快取列表
如果設定了最大的快取數,就刪除第0個快取。新增最新的快取。
並且給元件新增一個keepAlive變數為true,當元件初始化的時候,不再初始化。
三十三、vue-router有幾種勾點函數?執行流程如何?
勾點函數有三種:
三十四、vuerouter的兩種模式的區別
- vue-router中有三種模式,分別是hash、history、abstract
- abstract在不支援瀏覽器的API換景使用
- hash模式相容性好,但是不美觀,不利於SEO
- history美觀,historyAPI+popState,但是重新整理會出現404
三十五、談談Vue的效能優化有哪些?
- 資料層級不要過深,合理的設定響應式資料
- 使用資料時,快取值的結果,不頻繁取值
- 合理設定key
- v-show(頻繁切換效能高)和v-if的合理使用
- 控制元件的粒度 -> Vue採用元件級別更新
- 採用函數式元件 -> 函數式組價開銷低
- 採用非同步元件 -> 藉助webpack的分包策略
- 使用keep-alive來快取元件
- 虛擬捲動、時間分片等策略
- 打包優化
三十六、談談你對Vuex的理解?
Vuex是專門為vue提供的全域性狀態管理系統,用於多個元件中的資料共用、資料快取。
問題:無法持久化。
- mutation 主要修改狀態,同步執行
- action 執行業務程式碼,方便複用,邏輯可以為非同步。不能直接修改狀態。
三十七、vue中使用了哪些設計模式?
- 工場模式:傳入引數就可以建立範例(虛擬節點的建立)
- 釋出訂閱模式:eventBus
- 觀察者模式:watch和dep
- 代理模式:_data屬性、proxy、防抖、節流
- 中介者模式:vuex
- 策略模式
- 外觀模式
原文地址:https://juejin.cn/post/7043074656047202334
作者:海明月
(學習視訊分享:)