面試題聯盟之 VUE 篇

菜頭同學發表於2020-04-06

面試題聯盟之 VUE 篇

1.SPA 單頁面的理解

SPA( single-page application )僅在 Web 頁面初始化時載入相應的 HTML、JavaScript 和 CSS。一旦頁面載入完成,SPA 不會因為使用者的操作而進行頁面的重新載入或跳轉;取而代之的是利用路由機制實現 HTML 內容的變換,UI 與使用者的互動,避免頁面的重新載入。

優點:

使用者體驗好、快,內容的改變不需要重新載入整個頁面,避免了不必要的跳轉和重複渲染;

基於上面一點,SPA 相對對伺服器壓力小;

前後端職責分離,架構清晰,前端進行互動邏輯,後端負責資料處理;

缺點:

初次載入耗時多:為實現單頁 Web 應用功能及顯示效果,需要在載入頁面的時候將 JavaScript、CSS 統一載入,部分頁面按需載入;

前進後退路由管理:由於單頁應用在一個頁面中顯示所有的內容,所以不能使用瀏覽器的前進後退功能,所有的頁面切換需要自己建立堆疊管理;

SEO 難度較大:由於所有的內容都在一個頁面中動態替換顯示,所以在 SEO 上其有著天然的弱勢。

2.v-show 與 v-if 有何區別?

v-if 是真正的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子元件適當地被銷燬和重建;也是短路的:如果在初始渲染時條件為假,則什麼也不做——直到條件第一次變為真時,才會開始渲染條件塊。

v-show 就簡單得多——不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS 的 “display” 屬性進行切換。

所以,v-if 適用於在執行時很少改變條件,不需要頻繁切換條件的場景;v-show 則適用於需要非常頻繁切換條件的場景。

3.computed 和 watch 的區別和運用場景?

computed: 是計算屬性,依賴其它屬性值,並且 computed 的值有快取,只有它依賴的屬性值發生改變,下一次獲取 computed 的值時才會重新計算 computed 的值;

需要進行數值計算,並且依賴於其它資料時,應該使用 computed,因為可以利用 computed 的快取特性,避免每次獲取值時,都要重新計算;

watch: 更多的是「觀察」的作用,類似於某些資料的監聽回撥 ,每當監聽的資料變化時都會執行回撥進行後續操作;

需要在資料變化時執行非同步或開銷較大的操作時,應該使用 watch,使用 watch 選項允許我們執行非同步操作 ( 訪問一個 API ),限制我們執行該操作的頻率,並在我們得到最終結果前,設定中間狀態。這些都是計算屬性無法做到的。

4.元件中 data 為什麼是函式

元件中的data寫成一個函式,資料以函式返回值形式定義,這樣每複用一次元件,就會返回一份新的data,類似於給每個元件例項建立一個私有的資料空間,讓各個元件例項維護各自的資料。

而單純的寫成物件形式,就使得所有元件例項共用了一份data,就會造成一個變了全都會變的結果。

5.談談你對 Vue 生命週期的理解?

Vue 例項有一個完整的生命週期,也就是從開始建立、初始化資料、編譯模版、掛載 Dom -> 渲染、更新 -> 渲染、解除安裝等一系列過程,我們稱這是 Vue 的生命週期。

生命週期函式:

beforeCreate:元件例項被建立之初,元件的屬性生效之前

created:元件例項已經完全建立,屬性也繫結,但真實 dom 還沒有生成,$el 還不可用

beforeMount:在掛載開始之前被呼叫:相關的 render 函式首次被呼叫

mounted:el 被新建立的 vm.$el 替換,並掛載到例項上去之後呼叫該鉤子

beforeUpdate:元件資料更新之前呼叫,發生在虛擬 DOM 打補丁之前

update:元件資料更新之後

activited:keep-alive 專屬,元件被啟用時呼叫

deactivated:keep-alive 專屬,元件被銷燬時呼叫

beforeDestory:元件銷燬前呼叫

destoryed:元件銷燬後呼叫

6.元件間的通訊

父子 props/event children ref provide/inject

兄弟 bus vuex

跨級 bus vuex provide inject

7.雙向繫結原理

這個問題幾乎是面試必問的,回答也是有深有淺,如果本身對這個原理理解不深沒必要長篇大論給自己挖坑,基本上要知道核心的 API 是通過 Object.defineProperty() 來劫持各個屬性的setter / getter,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥,這也是為什麼 Vue.js 2.x 不支援 IE8 的原因(IE 8 不支援此 API,且無法通過 polyfill 實現)

8.介紹nextTick()

在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後,立即使用這個回撥函式,獲取更新後的 DOM。

  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
// 修改資料複製程式碼vm.msg = 'Hello'複製程式碼// DOM 還未更新複製程式碼Vue.nextTick(function () {複製程式碼  // DOM 更新複製程式碼})複製程式碼

9.在哪個生命週期內呼叫非同步請求?

可以在鉤子函式 created、beforeMount、mounted 中進行呼叫,因為在這三個鉤子函式中,data 已經建立,可以將服務端端返回的資料進行賦值。但是本人推薦在 created 鉤子函式中呼叫非同步請求,因為在 created 鉤子函式中呼叫非同步請求有以下優點:

能更快獲取到服務端資料,減少頁面 loading 時間;

ssr 不支援 beforeMount 、mounted 鉤子函式,所以放在 created 中有助於一致性;

10.vue-router有哪幾種導航鉤子?

三種,

第一種:是全域性導航鉤子:router.beforeEach(to,from,next),作用:跳轉前進行判斷攔截。

第二種:元件內的鉤子

第三種:單獨路由獨享元件

11.mvvm框架是什麼?哪些場景適合?

一個model+view+viewModel框架,資料模型model,viewModel連線兩個

區別:vue資料驅動,通過資料來顯示檢視層而不是節點操作。

場景:資料操作比較多的場景,更加便捷

12.簡單介紹一下Vuex

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。每一個 Vuex 應用的核心就是 store(倉庫)。“store” 基本上就是一個容器,它包含著你的應用中大部分的狀態 ( state )。

(1)Vuex 的狀態儲存是響應式的。當 Vue 元件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的元件也會相應地得到高效更新。

(2)改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化。

主要包括以下幾個模組:

State:定義了應用狀態的資料結構,可以在這裡設定預設的初始狀態。

Getter:允許元件從 Store 中獲取資料,mapGetters 輔助函式僅僅是將 store 中的 getter 對映到區域性計算屬性。

Mutation:是唯一更改 store 中狀態的方法,且必須是同步函式。

Action:用於提交 mutation,而不是直接變更狀態,可以包含任意非同步操作。

Module:允許將單一的 Store 拆分為多個 store 且同時儲存在單一的狀態樹中。

13.vue-router 路由模式有幾種?

vue-router 有 3 種路由模式:hash、history、abstract,3 種路由模式的說明如下:

hash: 使用 URL hash 值來作路由。支援所有瀏覽器,包括不支援 HTML5 History Api 的瀏覽器;

history : 依賴 HTML5 History API 和伺服器配置。具體可以檢視 HTML5 History 模式;

abstract : 支援所有 JavaScript 執行環境,如 Node.js 伺服器端。如果發現沒有瀏覽器的 API,路由會自動強制進入這個模式.

14.Proxy 與 Object.defineProperty 優劣對比(vue3.0使用的就是porxy)

Proxy 的優勢如下:

Proxy 可以直接監聽物件而非屬性;

Proxy 可以直接監聽陣列的變化;

Proxy 有多達 13 種攔截方法,不限於 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具備的;

Proxy 返回的是一個新物件,我們可以只操作新的物件達到目的,而 Object.defineProperty 只能遍歷物件屬性直接修改;

Proxy 作為新標準將受到瀏覽器廠商重點持續的效能優化,也就是傳說中的新標準的效能紅利;

Object.defineProperty 的優勢如下:

相容性好,支援 IE9,而 Proxy 的存在瀏覽器相容性問題,而且無法用 polyfill 磨平,因此 Vue 的作者才宣告需要等到下個大版本( 3.0 )才能用 Proxy 重寫。

15.Vue 怎麼解決物件新增屬性不能響應的問題 ?

Vue 無法檢測到物件屬性的新增或刪除。由於 Vue 會在初始化例項時對屬性執行 getter/setter 轉化,所以屬性必須在 data 物件上存在才能讓 Vue 將它轉換為響應式的。

但是 Vue 提供了 Vue.set (object, propertyName, value) / vm.$set (object, propertyName, value) 來實現為物件新增響應式屬性

16.Vue 專案可以進行哪些優化?(加分項)

(1)程式碼層面的優化

v-if 和 v-show 區分使用場景

computed 和 watch 區分使用場景

v-for 遍歷必須為 item 新增 key,且避免同時使用 v-if

長列表效能優化

事件的銷燬

圖片資源懶載入

路由懶載入

第三方外掛的按需引入

優化無限列表效能

服務端渲染 SSR or 預渲染

(2)Webpack 層面的優化

Webpack 對圖片進行壓縮

減少 ES6 轉為 ES5 的冗餘程式碼

提取公共程式碼

模板預編譯

提取元件的 CSS

優化 SourceMap

構建結果輸出分析

Vue 專案的編譯優化

(3)基礎的 Web 技術的優化

開啟 gzip 壓縮

瀏覽器快取

CDN 的使用

使用 Chrome Performance 查詢效能瓶頸

相關文章