vue面試題+答案,2021前端面試


vue面試題+答案,2021前端面試

vue視頻教程系列:

Vue3+ElementPlus+Koa2 全棧開發后台系統

試看:點擊觀看

完整課程:點擊查看

Vue3.0高階實戰:開發高質量音樂Web app

試看:點擊觀看

完整課程:點擊查看

VUE全面教學+VUE開源項目超級實戰:

試看:點擊觀看

完整課程:點擊查看

最新Vue.JS教程快速入門到項目實戰(Vue3/VueJS技術詳解)

試看:點擊觀看

完整課程:點擊查看

最新最全前端畢設項目(小程序+VUE+Noed+React+uni app+Express+Mongodb)

試看:點擊觀看

完整課程:點擊查看

MVC 和 MVVM 區別

MVC

MVC 全名是 Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典范

  • Model(模型):是應用程序中用於處理應用程序數據邏輯的部分。通常模型對象負責在數據庫中存取數據
  • View(視圖):是應用程序中處理數據顯示的部分。通常視圖是依據模型數據創建的
  • Controller(控制器):是應用程序中處理用戶交互的部分。通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據

MVC 的思想:一句話描述就是 Controller 負責將 Model 的數據用 View 顯示出來,換句話說就是在 Controller 里面把 Model 的數據賦值給 View。

MVVM

MVVM 新增了 VM 類

  • ViewModel 層:做了兩件事達到了數據的雙向綁定 一是將【模型】轉化成【視圖】,即將后端傳遞的數據轉化成所看到的頁面。實現的方式是:數據綁定。二是將【視圖】轉化成【模型】,即將所看到的頁面轉化成后端的數據。實現的方式是:DOM 事件監聽。

MVVM 與 MVC 最大的區別就是:它實現了 View 和 Model 的自動同步,也就是當 Model 的屬性改變時,我們不用再自己手動操作 Dom 元素,來改變 View 的顯示,而是改變屬性后該屬性對應 View 層顯示會自動改變(對應Vue數據驅動的思想)

整體看來,MVVM 比 MVC 精簡很多,不僅簡化了業務與界面的依賴,還解決了數據頻繁更新的問題,不用再用選擇器操作 DOM 元素。因為在 MVVM 中,View 不知道 Model 的存在,Model 和 ViewModel 也觀察不到 View,這種低耦合模式提高代碼的可重用性

注意:Vue 並沒有完全遵循 MVVM 的思想 這一點官網自己也有說明

那么問題來了 為什么官方要說 Vue 沒有完全遵循 MVVM 思想呢?

  • 嚴格的 MVVM 要求 View 不能和 Model 直接通信,而 Vue 提供了$refs 這個屬性,讓 Model 可以直接操作 View,違反了這一規定,所以說 Vue 沒有完全遵循 MVVM。

vue是如何實現響應式數據的呢?(響應式數據原理)

Vue2: Object.defineProperty 重新定義 data 中所有的屬性, Object.defineProperty 可以使數據的獲取與設置增加一個攔截的功能,攔截屬性的獲取,進行依賴收集。攔截屬性的更新操作,進行通知。

具體的過程:首先Vue使用 initData 初始化用戶傳入的參數,然后使用 new Observer 對數據進行觀測,如果數據是一個對象類型就會調用 this.walk(value) 對對象進行處理,內部使用 defineeReactive 循環對象屬性定義響應式變化,核心就是使用 Object.defineProperty 重新定義數據。

那vue中是如何檢測數組變化的呢?

數組就是使用 object.defineProperty 重新定義數組的每一項,那能引起數組變化的方法我們都是知道的, pop push shift unshift splice sort reverse 這七種,只要這些方法執行改了數組內容,我就更新內容就好了,是不是很好理解。

  1. 是用來函數劫持的方式,重寫了數組方法,具體呢就是更改了數組的原型,更改成自己的,用戶調數組的一些方法的時候,走的就是自己的方法,然后通知視圖去更新。
  2. 數組里每一項可能是對象,那么我就是會對數組的每一項進行觀測,(且只有數組里的對象才能進行觀測,觀測過的也不會進行觀測)

vue3:改用 proxy ,可直接監聽對象數組的變化。

vue的優點

輕量級框架:只關注視圖層,是一個構建數據的視圖集合,大小只有幾十kb;

簡單易學:國人開發,中文文檔,不存在語言障礙 ,易於理解和學習;

雙向數據綁定:保留了angular的特點,在數據操作方面更為簡單;

組件化:保留了react的優點,實現了html的封裝和重用,在構建單頁面應用方面有着獨特的優勢;

視圖,數據,結構分離:使數據的更改更為簡單,不需要進行邏輯代碼的修改,只需要操作數據就能完成相關操作;

虛擬DOM:dom操作是非常耗費性能的,不再使用原生的dom操作節點,極大解放dom操作,但具體操作的還是dom不過是換了另一種方式;

運行速度更快:相比較與react而言,同樣是操作虛擬dom,就性能而言,vue存在很大的優勢。

為什么vue組件中data必須是一個函數?

對象為引用類型,當復用組件時,由於數據對象都指向同一個data對象,當在一個組件中修改data時,其他重用的組件中的data會同時被修改;而使用返回對象的函數,由於每次返回的都是一個新對象(Object的實例),引用地址不同,則不會出現這個問題。

v-if 和 v-show 的區別

v-if 在編譯過程中會被轉化成三元表達式,條件不滿足時不渲染此節點。

v-show 會被編譯成指令,條件不滿足時控制樣式將對應節點隱藏 (display:none)

為什么Vue采用異步渲染呢?

Vue 是組件級更新,如果不采用異步更新,那么每次更新數據都會對當前組件進行重新渲染,所以為了性能, Vue 會在本輪數據更新后,在異步更新視圖。核心思想 nextTick

dep.notify() 通知 watcher進行更新, subs[i].update 依次調用 watcher 的 update queueWatcher 將watcher 去重放入隊列, nextTick( flushSchedulerQueue )在下一tick中刷新watcher隊列(異步)。

父子組件生命周期調用順序(簡單)

渲染順序:先父后子,完成順序:先子后父

更新順序:父更新導致子更新,子更新完成后父

銷毀順序:先父后子,完成順序:先子后父

用VNode來描述一個DOM結構

虛擬節點就是用一個對象來描述一個真實的DOM元素。首先將 template (真實DOM)先轉成 ast ast 樹通過 codegen 生成 render 函數, render 函數里的 _c 方法將它轉為虛擬dom

diff算法

時間復雜度: 個樹的完全 diff 算法是一個時間復雜度為 O(n*3) ,vue進行優化轉化成 O(n)

理解:

  • 最小量更新, key 很重要。這個可以是這個節點的唯一標識,告訴 diff 算法,在更改前后它們是同一個DOM節點
    • 擴展 v-for 為什么要有 key ,沒有 key 會暴力復用,舉例子的話隨便說一個比如移動節點或者增加節點(修改DOM),加 key 只會移動減少操作DOM。
  • 只有是同一個虛擬節點才會進行精細化比較,否則就是暴力刪除舊的,插入新的。
  • 只進行同層比較,不會進行跨層比較。

diff算法的優化策略:四種命中查找,四個指針

  1. 舊前與新前(先比開頭,后插入和刪除節點的這種情況)
  2. 舊后與新后(比結尾,前插入或刪除的情況)
  3. 舊前與新后(頭與尾比,此種發生了,涉及移動節點,那么新前指向的節點,移動到舊后之后)
  4. 舊后與新前(尾與頭比,此種發生了,涉及移動節點,那么新前指向的節點,移動到舊前之前)

v-for 為什么要加 key

如果不使用 key,Vue 會使用一種最大限度減少動態元素並且盡可能的嘗試就地修改/復用相同類型元素的算法。key 是為 Vue 中 vnode 的唯一標記,通過這個 key,我們的 diff 操作可以更准確、更快速

更准確:因為帶 key 就不是就地復用了,在 sameNode 函數 a.key === b.key 對比中可以避免就地復用的情況。所以會更加准確。

更快速:利用 key 的唯一性生成 map 對象來獲取對應節點,比遍歷方式更快

vue-router 路由鈎子函數是什么 執行順序是什么

路由鈎子的執行流程, 鈎子函數種類有:全局守衛、路由守衛、組件守衛

完整的導航解析流程:

  1. 導航被觸發。
  2. 在失活的組件里調用 beforeRouteLeave 守衛。
  3. 調用全局的 beforeEach 守衛。
  4. 在重用的組件里調用 beforeRouteUpdate 守衛 (2.2+)。
  5. 在路由配置里調用 beforeEnter。
  6. 解析異步路由組件。
  7. 在被激活的組件里調用 beforeRouteEnter。
  8. 調用全局的 beforeResolve 守衛 (2.5+)。
  9. 導航被確認。
  10. 調用全局的 afterEach 鈎子。
  11. 觸發 DOM 更新。
  12. 調用 beforeRouteEnter 守衛中傳給 next 的回調函數,創建好的組件實例會作為回調函數的參數傳入。

談一下對 vuex 的個人理解

vuex 是專門為 vue 提供的全局狀態管理系統,用於多個組件中數據共享、數據緩存等。(無法持久化、內部核心原理是通過創造一個全局實例 new Vue)

主要包括以下幾個模塊:

  • State:定義了應用狀態的數據結構,可以在這里設置默認的初始狀態。
  • Getter:允許組件從 Store 中獲取數據,mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性。
  • Mutation:是唯一更改 store 中狀態的方法,且必須是同步函數。
  • Action:用於提交 mutation,而不是直接變更狀態,可以包含任意異步操作。
  • Module:允許將單一的 Store 拆分為多個 store 且同時保存在單一的狀態樹中。

keep-alive 使用場景和原理

keep-alive 是 Vue 內置的一個組件,可以實現組件緩存,當組件切換時不會對當前組件進行卸載。

  • 常用的兩個屬性 include/exclude,允許組件有條件的進行緩存。
  • 兩個生命周期 activated/deactivated,用來得知當前組件是否處於活躍狀態。
  • keep-alive 的中還運用了 LRU(最近最少使用) 算法,選擇最近最久未使用的組件予以淘汰。

Vue.extend 作用和原理

官方解釋:Vue.extend 使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象。

其實就是一個子類構造器 是 Vue 組件的核心 api 實現思路就是使用原型繼承的方法返回了 Vue 的子類 並且利用 mergeOptions 把傳入組件的 options 和父類的 options 進行了合並

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:

  1. computed是計算屬性,也就是計算值,它更多用於計算值的場景
  2. computed具有緩存性,computed的值在getter執行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調用對應的getter來計算
  3. computed適用於計算比較消耗性能的計算場景

watch:

  1. 更多的是「觀察」的作用,類似於某些數據的監聽回調,用於觀察props $emit或者本組件的值,當數據變化時來執行回調進行后續操作
  2. 無緩存性,頁面重新渲染時值不變化也會執行

小結:

  1. 當我們要進行數值計算,而且依賴於其他數據,那么把這個數據設計為computed
  2. 如果你需要在某個數據變化時做一些事情,使用watch來觀察這個數據變化

虛擬DOM的優劣如何?

優點:

  • 保證性能下限: 虛擬DOM可以經過diff找出最小差異,然后批量進行patch,這種操作雖然比不上手動優化,但是比起粗暴的DOM操作性能要好很多,因此虛擬DOM可以保證性能下限
  • 無需手動操作DOM: 虛擬DOM的diff和patch都是在一次更新中自動進行的,我們無需手動操作DOM,極大提高開發效率
  • 跨平台: 虛擬DOM本質上是JavaScript對象,而DOM與平台強相關,相比之下虛擬DOM可以進行更方便地跨平台操作,例如服務器渲染、移動端開發等等

缺點:

  • 無法進行極致優化: 在一些性能要求極高的應用中虛擬DOM無法進行針對性的極致優化,比如VScode采用直接手動操作DOM的方式進行極端的性能優化

虛擬DOM實現原理?

  • 虛擬DOM本質上是JavaScript對象,是對真實DOM的抽象
  • 狀態變更時,記錄新樹和舊樹的差異
  • 最后把差異更新到真正的dom中

Vue 初始化頁面閃動問題如何解決?

出現該問題是因為在 Vue 代碼尚未被解析之前,尚無法控制頁面中 DOM 的顯示,所以會看見模板字符串等代碼。
解決方案是,在 css 代碼中添加 v-cloak 規則,同時在待編譯的標簽上添加 v-cloak 屬性:

[v-cloak] { display: none; }

<div v-cloak>
  {{ message }}
</div>

Vue-router 路由有哪些模式?

一般有兩種模式:
(1)hash 模式:后面的 hash 值的變化,瀏覽器既不會向服務器發出請求,瀏覽器也不會刷新,每次 hash 值的變化會觸發 hashchange 事件。
(2)history 模式:利用了 HTML5 中新增的 pushState() 和 replaceState() 方法。這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向后端發送請求。

$nextTick 是什么?

Vue 實現響應式並不是在數據發生后立即更新 DOM,使用 vm.$nextTick 是在下次 DOM 更新循環結束之后立即執行延遲回調。在修改數據之后使用,則可以在回調中獲取更新后的 DOM

Vue 中 computed 和 watch 有什么區別?

計算屬性 computed
(1)支持緩存,只有依賴數據發生變化時,才會重新進行計算函數;
(2)計算屬性內不支持異步操作
(3)計算屬性的函數中都有一個 get(默認具有,獲取計算屬性)和 set(手動添加,設置計算屬性)方法;
(4)計算屬性是自動監聽依賴值的變化,從而動態返回內容。

偵聽屬性 watch
(1)不支持緩存,只要數據發生變化,就會執行偵聽函數;
(2)偵聽屬性內支持異步操作
(3)偵聽屬性的值可以是一個對象,接收 handler 回調,deep,immediate 三個屬性
(3)監聽是一個過程,在監聽的值變化時,可以觸發一個回調,並做一些其他事情

action 與 mutation 的區別

  • mutation 是同步更新, $watch 嚴格模式下會報錯
  • action 是異步操作,可以獲取數據后調用 mutation 提交最終數據

談談對keep-alive的了解

keep-alive 可以實現組件的緩存,當組件切換時不會對當前組件進行卸載。常用的2個屬性 include/exclude ,2個生命周期 activated deactivated

Vue 模板編譯原理

Vue 的編譯過程就是將 template 轉化為 render 函數的過程 分為以下三步

第一步是將 模板字符串 轉換成 element ASTs(解析器)
第二步是對 AST 進行靜態節點標記,主要用來做虛擬DOM的渲染優化(優化器)
第三步是 使用 element ASTs 生成 render 函數代碼字符串(代碼生成器)

Vue 修飾符有哪些

事件修飾符

  • .stop 阻止事件繼續傳播
  • .prevent 阻止標簽默認行為
  • .capture 使用事件捕獲模式,即元素自身觸發的事件先在此處處理,然后才交由內部元素進行處理
  • .self 只當在 event.target 是當前元素自身時觸發處理函數
  • .once 事件將只會觸發一次
  • .passive 告訴瀏覽器你不想阻止事件的默認行為

v-model 的修飾符

  • .lazy 通過這個修飾符,轉變為在 change 事件再同步
  • .number 自動將用戶的輸入值轉化為數值類型
  • .trim 自動過濾用戶輸入的首尾空格

鍵盤事件的修飾符

  • .enter
  • .tab
  • .delete (捕獲“刪除”和“退格”鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系統修飾鍵

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠標按鈕修飾符

  • .left
  • .right
  • .middle

Vue性能優化

編碼優化

  • 事件代理
  • keep-alive
  • 拆分組件
  • key 保證唯一性
  • 路由懶加載、異步組件
  • 防抖節流

Vue加載性能優化

  • 第三方模塊按需導入( babel-plugin-component
  • 圖片懶加載

用戶體驗

  • app-skeleton 骨架屏
  • shellap p殼
  • pwa

SEO優化

  • 預渲染


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM