前端面試題彙總(主要爲 Vue)

前端面試題彙總

1. 談談你對MVVM開發模式的理解

MVVM分爲Model、View、ViewModel三者。javascript

1)Model:表明數據模型,數據和業務邏輯都在Model層中定義;css

2)View:表明UI視圖,負責數據的展現;html

3)ViewModel:負責監聽Model中數據的改變而且控制視圖的更新,處理用戶交互操做;前端

Model和View並沒有直接關聯,而是經過ViewModel來進行聯繫的,Model和ViewModel之間有着雙向數據綁定的聯繫。所以當Model中的數據改變時會觸發View層的刷新,View中因爲用戶交互操做而改變的數據也會在Model中同步。vue

這種模式實現了Model和View的數據自動同步,所以開發者只須要專一對數據的維護操做便可,而不須要本身操做dom。java

2. Vue 有哪些指令?

v-html、v-show、v-if、v-for等等。webpack

3. v-if 和 v-show 有什麼區別?

v-show 僅僅控制元素的顯示方式,將 display 屬性在 block 和 none 來回切換;而v-if會控制這個 DOM 節點的存在與否。當咱們須要常常切換某個元素的顯示/隱藏時,使用v-show會更加節省性能上的開銷;當只須要一次顯示或隱藏時,使用v-if更加合理。web

4. 簡述Vue的響應式原理

當一個Vue實例建立時,vue會遍歷data選項的屬性,用 Object.defineProperty 將它們轉爲getter/setter而且在內部追蹤相關依賴,在屬性被訪問和修改時通知變化。 每一個組件實例都有相應的watcher程序實例,它會在組件渲染的過程當中把屬性記錄爲依賴,以後當依賴項的setter被調用時,會通知watcher從新計算,從而導致它關聯的組件得以更新。面試

 

5. Vue中如何在組件內部實現一個雙向數據綁定?

假設有一個輸入框組件,用戶輸入時,同步父組件頁面中的數據。gulp

具體思路:父組件經過props傳值給子組件,子組件經過 $emit 來通知父組件修改相應的props值,具體實現以下:

import Vue from 'vue'

const component = {
 props: ['value'],
 template: `
   <div>
     <input type="text" @input="handleInput" :value="value">
   </div>
 `,
 data () {
   return {
   }
 },
 methods: {
   handleInput (e) {
     this.$emit('input', e.target.value)
   }
 }
}
new Vue({
 components: {
   CompOne: component
 },
 el: '#root',
 template: `
   <div>
     <comp-one :value1="value" @input="value = arguments[0]"></comp-one>
   </div>
 `,
 data () {
   return {
     value: '123'
   }
 }
})

  

能夠看到,當輸入數據時,父子組件中的數據是同步改變的:

 

咱們在父組件中作了兩件事,一是給子組件傳入props,二是監聽input事件並同步本身的value屬性。那麼這兩步操做可否再精簡一下呢?答案是能夠的,你只須要修改父組件:

template: `
   <div>
     <!--<comp-one :value1="value" @input="value = arguments[0]"></comp-one>-->
     <comp-one v-model="value"></comp-one>
   </div>
 `

v-model 實際上會幫咱們完成上面的兩步操做。

6. Vue中如何監控某個屬性值的變化?

好比如今須要監控data中, obj.a 的變化。Vue中監控對象屬性的變化你能夠這樣:

watch: {
     obj: {
     handler (newValue, oldValue) {
       console.log('obj changed')
     },
     deep: true
   }
 }

deep屬性表示深層遍歷,可是這麼寫會監控obj的全部屬性變化,並非咱們想要的效果,因此作點修改:

watch: {
  'obj.a': {
     handler (newName, oldName) {
       console.log('obj.a changed')
     }
  }
 }

還有一種方法,能夠經過computed 來實現,只須要:

computed: {
   a1 () {
     return this.obj.a
   }
}

利用計算屬性的特性來實現,當依賴改變時,便會從新計算一個新值。

7. Vue中給data中的對象屬性添加一個新的屬性時會發生什麼,如何解決?

示例:

<template>
 <div>
   <ul>
     <li v-for="value in obj" :key="value">
       {{value}}
     </li>
   </ul>
   <button @click="addObjB">添加obj.b</button>
 </div>
</template>
<script>
export default {
 data () {
   return {
     obj: {
       a: 'obj.a'
     }
   }
 },
 methods: {
   addObjB () {
     this.obj.b = 'obj.b'
     console.log(this.obj)
   }
 }
}
</script>
<style></style>

點擊button會發現, obj.b 已經成功添加,可是視圖並未刷新:

緣由在於在Vue實例建立時, obj.b 並未聲明,所以就沒有被Vue轉換爲響應式的屬性,天然就不會觸發視圖的更新,這時就須要使用Vue的全局api—— $set()

addObjB () {
     // this.obj.b = 'obj.b'
     this.$set(this.obj, 'b', 'obj.b')
     console.log(this.obj)
}

$set() 方法至關於手動的去把 obj.b 處理成一個響應式的屬性,此時視圖也會跟着改變了:

8. delete和Vue.delete刪除數組的區別

delete只是被刪除的元素變成了 empty/undefined 其餘的元素的鍵值仍是不變。

Vue.delete 直接刪除了數組 改變了數組的鍵值。

var a=[1,2,3,4]
var b=[1,2,3,4]
delete a[1]
console.log(a)
this.$delete(b,1)
console.log(b)

  

9.如何優化SPA應用的首屏加載速度慢的問題?

1)將公用的JS庫經過script標籤外部引入,減少 app.bundel 的大小,讓瀏覽器並行下載資源文件,提升下載速度;

2)在配置 路由時,頁面和組件使用懶加載的方式引入,進一步縮小 app.bundel 的體積,在調用某個組件時再加載對應的js文件;

3)加一個首屏loading圖,提高用戶體驗;

10. 前端如何優化網站性能?

1)減小 HTTP 請求數量

在瀏覽器與服務器進行通訊時,主要是經過 HTTP 進行通訊。瀏覽器與服務器須要通過三次握手,每次握手須要花費大量時間。並且不一樣瀏覽器對資源文件併發請求數量有限(不一樣瀏覽器容許併發數),一旦 HTTP 請求數量達到必定數量,資源請求就存在等待狀態,這是很致命的,所以減小 HTTP 的請求數量能夠很大程度上對網站性能進行優化。

CSS Sprites

國內俗稱CSS精靈,這是將多張圖片合併成一張圖片達到減小HTTP請求的一種解決方案,能夠經過CSS的background屬性來訪問圖片內容。這種方案同時還能夠減小圖片總字節數。

合併 CSS 和 JS 文件

如今前端有不少工程化打包工具,如:grunt、gulp、webpack等。爲了減小 HTTP 請求數量,能夠經過這些工具再發布前將多個CSS或者多個JS合併成一個文件。

採用 lazyLoad

俗稱懶加載,能夠控制網頁上的內容在一開始無需加載,不須要發請求,等到用戶操做真正須要的時候當即加載出內容。這樣就控制了網頁資源一次性請求數量。

2)控制資源文件加載優先級

瀏覽器在加載HTML內容時,是將HTML內容從上至下依次解析,解析到link或者script標籤就會加載href或者src對應連接內容,爲了第一時間展現頁面給用戶,就須要將CSS提早加載,不要受 JS 加載影響。

通常狀況下都是CSS在頭部,JS在底部。

3)利用瀏覽器緩存

瀏覽器緩存是將網絡資源存儲在本地,等待下次請求該資源時,若是資源已經存在就不須要到服務器從新請求該資源,直接在本地讀取該資源。

4)減小重排(Reflow)

基本原理:重排是DOM的變化影響到了元素的幾何屬性(寬和高),瀏覽器會從新計算元素的幾何屬性,會使渲染樹中受到影響的部分失效,瀏覽器會驗證 DOM 樹上的全部其它結點的visibility屬性,這也是Reflow低效的緣由。若是Reflow的過於頻繁,CPU使用率就會急劇上升。

減小Reflow,若是須要在DOM操做時添加樣式,儘可能使用 增長class屬性,而不是經過style操做樣式。

5)減小 DOM 操做
6)圖標使用 IconFont 替換

11. 網頁從輸入網址到渲染完成經歷了哪些過程?

大體能夠分爲以下7步:

1)輸入網址;

2)發送到DNS服務器,並獲取域名對應的web服務器對應的ip地址;

3)與web服務器創建TCP鏈接;

4)瀏覽器向web服務器發送http請求;

5)web服務器響應請求,並返回指定url的數據(或錯誤信息,或重定向的新的url地址);

6)瀏覽器下載web服務器返回的數據及解析html源文件;

7)生成DOM樹,解析css和js,渲染頁面,直至顯示完成;

12. jQuery獲取的dom對象和原生的dom對象有何區別?

js原生獲取的dom是一個對象,jQuery對象就是一個數組對象,其實就是選擇出來的元素的數組集合,因此說他們二者是不一樣的對象類型不等價。

原生DOM對象轉jQuery對象:

var box = document.getElementById('box');
var $box = $(box);
jQuery對象轉原生DOM對象:
var $box = $('#box');
var box = $box[0];

13. jQuery如何擴展自定義方法

(jQuery.fn.myMethod=function () {
      alert('myMethod');
})
// 或者:
(function ($) {
       $.fn.extend({
            myMethod : function () {
                 alert('myMethod');
            }
       })
})(jQuery)

使用:

$("#div").myMethod();

相關文章
相關標籤/搜索