Vue高級面試題彙總

說說你對SPA單頁面的理解,它的優缺點分別是什麼?

參考答案

是一種只須要將單個頁面加載到服務器之中的web應用程序。當瀏覽器向服務器發出第一個請求時,服務器會返回一個index.html文件,它所需的js,css等會在顯示時統一加載,部分頁面按需加載。url地址變化時不會向服務器在請求頁面,經過路由才實現頁面切換。javascript

優勢:css

  • 良好的交互體驗,用戶不須要從新刷新頁面,獲取數據也是經過Ajax異步獲取,頁面顯示流暢;
  • 良好的先後端工做分離模式。

缺點:html

  • SEO難度較高,因爲全部的內容都在一個頁面中動態替換顯示,因此在SEO上其有着自然的弱勢。
  • 首屏加載過慢(初次加載耗時多)

SPA單頁面的實現方式有哪些?

參考答案
  • 在hash模式中,在window上監聽hashchange事件(地址欄中hash變化觸發)驅動界面變化;
  • 在history模式中,在window上監聽popstate事件(瀏覽器的前進或後退按鈕的點擊觸發)驅動界面變化,監聽a連接點擊事件用history.pushState、history.replaceState方法驅動界面變化;
  • 直接在界面用顯示隱藏事件驅動界面變化。

說說你對MVC、MVP、MVVM模式的理解

參考答案

在以往開發程序過程當中,界面佈局代碼、界面交互邏輯代碼、業務邏輯代碼三者代碼都是混在一塊兒的。隨着業務需求愈來愈大,代碼愈來愈複雜,不只致使開發困難,更是致使維護代碼更困難,特別是維護別人的代碼。vue

因此就出現MVC模式來解決這個問題,其中M表明Model,專門來處理、存儲數據。V表明View,專門來處理頁面的展現。C表明Controller專門處理業務邏輯。java

用戶操做View,View發送指令到Control,完成業務邏輯處理後,要求Model處理相應的數據,將處理好的數據發送到View,要求View把這些數據展現給用戶。node

固然用戶也能夠直接下發指令到Control,完成對應業務邏輯處理後,要求Model處理相應的數據,將處理好的數據發送到View,要求View把這些數據展現給用戶。webpack

也能夠經過View直接要求Moder處理數據,將處理好的數據發送到View,要求View把這些數據展現給用戶。ios

然而在MVC模式中,Model、Control、View三者相互依賴,修改起來要兼顧其餘二者,仍是很是困難。git

因此又出現了MVP模式來解決這個問題,在MVP模式中P表明Presenter替代原來的Control。github

當用戶操做View,View發送指令到Presenter,完成業務邏輯處理後,要求Model處理相應的數據,將處理好的數據返回到Presenter中,Presenter將數據發送到View中,要求View把這些數據展現給用戶。

MVP模式中,Presenter將View和Model徹底隔離開,Presenter和View相互依賴,Presenter和Model相互依賴,View和Model再也不相互依賴,使代碼耦合下降。

由於Presenter和View相互依賴,這樣Presenter就沒辦法單獨作單元測試,非得等到View作好之後才行。因此對View分割一部分叫作View接口,Presenter只依賴View接口,這樣Presenter不用依賴View就能夠測試了,而且也增長了複用性,只要View實現了View接口部分,Presenter就能夠大發神威。

然而在MVP模式中,由於讓Presenter發送數據到View,讓View展現,仍然須要大量的、煩人的代碼,這實在是一件不舒服的事情。 那麼可不可讓View在Model變化時自動更新。

因此出現了MVVM模式來實現這個設想,其中VM表明ViewModel負責視圖顯示邏輯和監聽視圖變化,M表明Model變成處理業務邏輯和數據。

當用戶操做View時,ViewModel監聽到View的變化,會通知Model中對應的方法進行業務邏輯和數據處理,處理完畢後,ViewModel會監聽到自動讓View作出相應的更新。ViewModel能夠對應多個View,具備很強的複用性。

在Vue項目中。new Vue()就是一個ViewModel,View就是template模板。Model就是Vue的選項如data、methods等。在開發過程咱們只關注View怎麼展現,Model怎麼處理業務邏輯和數據。不要去管處理業務邏輯和數據後怎麼讓View更新,View上有操做,怎麼讓Model處理這個操做,這些統統交給ViewModel來實現,大大下降了開發成本。

說說你對Object.defineProperty的理解

參考答案
  • Object.defineProperty(obj,prop,descriptor)方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。
    • obj:要在其上定義屬性的對象。
    • prop:要定義或修改的屬性的名稱。
    • descriptor:將被定義或修改的屬性描述符。
  • descriptor屬性描述符主要有兩種形式:數據描述符和存取描述符。描述符必須是這兩種形式之一;不能同時是二者。
    • 數據描述符和存取描述符共同擁有
      • configurable:特性表示對象的屬性是否能夠被刪除,以及除value和writable特性外的其餘特性是否能夠被修改。默認爲false。
      • enumerable:當該屬性的enumerable爲true時,該屬性才能夠在for...in循環和Object.keys()中被枚舉。默認爲false。
    • 數據描述符
      • value:該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲undefined。
      • writable:當且僅當該屬性的writable爲true時,value才能被賦值運算符改變。默認爲false。
    • 存取描述符
      • get:一個給屬性提供 getter的方法,若是沒有getter則爲undefined。當訪問該屬性時,該方法會被執行,方法執行時沒有參數傳入,可是會傳入this對象(因爲繼承關係,這裏的this並不必定是定義該屬性的對象)。默認爲undefined。
      • set:一個給屬性提供 setter的方法,若是沒有setter則爲undefined。當屬性值修改時,觸發執行該方法。該方法將接受惟一參數,即該屬性新的參數值。默認爲undefined。
  • 定義descriptor時,最好先把這些屬性都定義清楚,防止被繼承和繼承時出錯。
function Archiver() {
    var temperature = null;
    var archive = [];
    Object.defineProperty(this, 'temperature', {
        get: function() {
          console.log('get!');
          return temperature;
        },
        set: function(value) {
          temperature = value;
          archive.push({ val: temperature });
        }
    });
    this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
複製代碼

說說你對Proxy的理解

參考答案 官方定義:proxy對象用於定義基本操做的自定義行爲(如屬性查找,賦值,枚舉,函數調用等)。

通俗來講是在對目標對象的操做以前提供了攔截,對外界的操做進行過濾和修改某些操做的默認行爲,能夠不直接操做對象自己,而是經過操做對象的代理對象來間接來操做對象。

let proxy = new Proxy(target, handler)

  • target 是用 Proxy 包裝的目標對象(能夠是任何類型的對象,包括原生數組,函數,甚至另外一個代理);
  • handler 一個對象,其屬性是當執行一個操做時定義代理的行爲的函數,也就是自定義的行爲。

handle能夠爲{},可是不能爲null,不然會報錯

Proxy 目前提供了 13 種可代理操做,比較經常使用的

  • handler.get(target,property,receiver)獲取值攔截
  • handler.set(target,property,value,receiver)設置值攔截
  • handler.has(target,prop)in 操做符攔截
let obj = {
	a : 1,
	b : 2
}
let test = new Proxy(obj,{
    get : function (target,property) {
        return property in target ? target[property] : 0
    },
    set : function (target,property,value) {
        target[property] = 6;
    },
    has: function (target,prop){
        if(prop == 'b'){
            target[prop] = 6;
        }
        return prop in target;
    },
})

console.log(test.a);        // 1
console.log(test.c);        // 0

test.a = 3;
console.log(test.a)         // 6

if('b' in test){
    console.log(test)       // Proxy {a: 6, b: 6}
}
複製代碼

Object.defineProperty和Proxy的區別

參考答案
  • Object.defineProperty
    • 不能監聽到數組length屬性的變化;
    • 不能監聽對象的添加;
    • 只能劫持對象的屬性,所以咱們須要對每一個對象的每一個屬性進行遍歷。
  • Proxy
    • 能夠監聽數組length屬性的變化;
    • 能夠監聽對象的添加;
    • 可代理整個對象,不須要對對象進行遍歷,極大提升性能;
    • 多達13種的攔截遠超Object.defineProperty只有get和set兩種攔截。

Vue的模板語法用的是哪一個web模板引擎的嗎?說說你對這模板引擎的理解?

參考答案

採用的是Mustache的web模板引擎mustache.js

<script type="text/javascript" src="./mustache.js"></script>
<script type="text/javascript">
    var data = {
        "company": "Apple",
    }

    var tpl = '<h1>Hello {{company}}</h1>';
    var html = Mustache.render(tpl, data);

    console.log(html);
</script>
複製代碼

你認爲Vue的核心是什麼?

參考答案

Vue.js 的核心是一個容許採用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統。

以上是官方原話,從中能夠得知Vue的核心是模板語法和數據渲染。

說說你對單向數據流和雙向數據流的理解

參考答案

單向數據流是指數據只能從父級向子級傳遞數據,子級不能改變父級向子級傳遞的數據。

雙向數據流是指數據從父級向子級傳遞數據,子級能夠經過一些手段改變父級向子級傳遞的數據。

好比用v-model.sync來實現雙向數據流。

什麼是雙向綁定?原理是什麼?

參考答案

雙向綁定是指數據模型(Module)和視圖(View)之間的雙向綁定。

其原理是採用數據劫持結合發佈者-訂閱者模式的方式來實現。

Vue中先遍歷data選項中全部的屬性(發佈者)用Object.defineProperty劫持這些屬性將其轉爲getter/setter。讀取數據時候會觸發getter。修改數據時會觸發setter。

而後給每一個屬性對應new Dep(),Dep是專門收集依賴、刪除依賴、向依賴發送消息的。先讓每一個依賴設置在Dep.target上,在Dep中建立一個依賴數組,先判斷Dep.target是否已經在依賴中存在,不存在的話添加到依賴數組中完成依賴收集,隨後將Dep.target置爲上一個依賴。

組件在掛載過程當中都會new一個Watcher實例。這個實例就是依賴(訂閱者)。Watcher第二參數式一個函數,此函數做用是更新且渲染節點。在首次渲染過程,會自動調用Dep方法來收集依賴,收集完成後組件中每一個數據都綁定上該依賴。當數據變化時就會在seeter中通知對應的依賴進行更新。在更新過程當中要先讀取數據,就會觸發Wacther的第二個函數參數。一觸發就再次再次自動調用Dep方法收集依賴,同時在此函數中運行patch(diff運算)來更新對應的DOM節點,完成了雙向綁定。

什麼是虛擬DOM?

參考答案 虛擬DOM是將狀態映射成視圖的衆多解決方案中的一種,其是經過狀態生成一個虛擬節點樹,而後使用虛擬節點樹進行渲染生成真實DOM,在渲染以前,會使用新生成的虛擬節點樹和上一次虛擬節點樹進行對比,只渲染不一樣的部分。

Vue中如何實現一個虛擬DOM?說說你的思路

參考答案 首先要構建一個VNode的類,DOM元素上的全部屬性在VNode類實例化出來的對象上都存在對應的屬性。例如tag表示一個元素節點的名稱,text表示一個文本節點的文本,chlidren表示子節點等。將VNode類實例化出來的對象進行分類,例如註釋節點、文本節點、元素節點、組件節點、函數式節點、克隆節點。

而後經過編譯將模板轉成渲染函數render,執行渲染函數render,在其中建立不一樣類型的VNode類,最後整合就能夠獲得一個虛擬DOM(vnode)。

最後經過patch將vnode和oldVnode進行比較後,生成真實DOM。

你瞭解Vue的diff算法嗎?

參考答案

你知道nextTick的原理嗎?

參考答案

說說你對Vue的template編譯的理解?

參考答案

Vue實例掛載的過程是什麼?

參考答案

在初始化的最後,若是檢測到選項有el屬性,則調用vm.$mount方法掛載vm,掛載的目標就是把模板渲染成最終的DOM

  • 第一步:確保vm.$options有render函數。

由於在不一樣構建版本上的掛載過程都不同,因此要對Vue原型上的$mount方法進行函數劫持。

首先建立一個變量mount將Vue原型上的$mount方法保存到這個變量上。而後Vue原型上的$mount方法被一個新的方法覆蓋。在這個新方法中調用mount這個原始方法。

經過el屬性進行獲取DOM元素。若是el是字符串,則使用document.querySelector獲取DOM元素並賦值給el。若是獲取不到,則建立一個空的div元素並賦值給el。若是el不是字符串,默認el是DOM元素,不進行處理。

判斷el是否是html元素或body元素,若是是則給出警告退出程序。

由於掛載後續過程當中須要render函數生成vnode,故要判斷$options選項中是否有render函數這個屬性,若是有直接調用原始的$mount方法。

若是沒有,則判斷template是否存在。若不存在則將el的outerHTML賦值給template。若存在,若是template是字符串且以#開頭,經過選擇符獲取DOM元素獲取innerHTML賦值給template,若是template已是DOM元素類型直接獲取innerHTML賦值給template。

而後將template編譯成代碼字符串並將代碼字符串轉成render函數,並賦值到vm.$options的render屬性上。

最後調用原始的$mount方法。

  • 第二步: 在原始的$mount方法,先觸發beforeMount鉤子函數,而後建立一個Watcher實例,在第二參數傳入一個函數vm._update

該函數是首次渲染和更新渲染做用,參數爲render函數(vnode),若是vm._vnode不存在則進行首次渲染。

同時vnode中被劫持的數據自動收集依賴。當vnode中被劫持的數據變化時候觸發對應的依賴,從而觸發vm._update進行更新渲染。

最後觸發mounted鉤子函數。

說下你對指令的理解?

參考答案

Vue爲何要求組件模板只能有一個根元素?

參考答案 當前的virtualDOM差別和diff算法在很大程度上依賴於每一個子組件老是隻有一個根元素。

你有用過事件總線(EventBus)嗎?說說你的理解

參考答案

使用Vue後怎麼針對搜索引擎作SEO優化?

參考答案

SSR解決了什麼問題?有作過SSR嗎?你是怎麼作的?

參考答案

axios是什麼?怎樣使用它?怎麼解決跨域的問題?

參考答案

ajax、fetch、axios這三都有什麼區別?

參考答案

爲什麼官方推薦使用axios而不用vue-resource?

參考答案

你有封裝過axios嗎?主要是封裝哪方面的?

參考答案

Vue開發過程你是怎麼作接口管理的?

參考答案

如何中斷axios的請求?

參考答案

若是將axios異步請求同步化處理?

參考答案

你瞭解axios的原理嗎?有看過它的源碼嗎?

參考答案

你有寫過自定義組件嗎?

參考答案

說說你對Vue組件的設計原則的理解

參考答案

寫出多種定義組件模板的方法

參考答案

你有使用過render函數嗎?有什麼好處?

參考答案

你瞭解什麼是函數式組件嗎?

參考答案

函數式組件的應用

你有使用過JSX嗎?說說你對JSX的理解?

參考答案

JSX就是Javascript和XML結合的一種格式。React發明了JSX,利用HTML語法來建立虛擬DOM。當遇到<,JSX就當HTML解析,遇到{就當JavaScript解析。

若是想擴展某個現有的Vue組件時,怎麼作呢?

參考答案
  • 用mixins混入
  • 用extends,比mixins先觸發
  • 用高階組件HOC封裝

你瞭解什麼是高階組件嗎?能否舉個例子說明下?

參考答案

怎麼在Vue中使用插件?

參考答案

組件和插件有什麼區別?

參考答案

爲何Vue使用異步更新組件?

參考答案

你有看過Vue推薦的風格指南嗎?列舉出你知道的幾條

參考答案

如何優化首頁的加載速度?

參考答案

Vue渲染大量數據時應該怎麼優化?說下你的思路!

參考答案 懶加載和分頁

你有使用過babel-polyfill模塊嗎?主要是用來作什麼的?

參考答案

爲何咱們寫組件的時候能夠寫在.vue裏呢?能夠是別的文件名後綴嗎?

參考答案

vue-loader是什麼?它有什麼做用?

參考答案

分析下Vue項目本地開發完成後部署到服務器後報404是什麼緣由呢?

參考答案

Vue首頁白屏是什麼問題引發的?如何解決呢?

參考答案

vue打包成最終的文件有哪些?

參考答案

如何解決vue打包vendor過大的問題?

參考答案

webpack打包vue速度太慢怎麼辦?

參考答案

vue部署上線前須要作哪些準備工做?

參考答案

說說你以爲認爲的Vue開發規範有哪些?

參考答案

你有使用過Vue開發多語言項目嗎?說說你的作法?

參考答案

用vue怎麼實現一個換膚的功能?

參考答案

對於即將到來的vue3.0特性你有什麼瞭解的嗎?

參考答案
相關文章
相關標籤/搜索