【前端芝士樹】Vue.js面試題整理 / 知識點梳理

【前端芝士樹】 Vue.js 面試題整理

MVVM是什麼?

MVVMModel-View-ViewModel 的縮寫。html

  • Model表明數據模型,也能夠在Model中定義數據修改和操做的業務邏輯。
  • View 表明UI 組件,它負責將數據模型轉化成UI 展示出來。
  • ViewModel 監聽模型數據的改變和控制視圖行爲、處理用戶交互,簡單理解就是一個同步View 和 Model的對象,鏈接Model和View。

在MVVM架構下,View 和 Model 之間並無直接的聯繫,而是經過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 所以View 數據的變化會同步到Model中,而Model 數據的變化也會當即反應到View 上。前端

ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而View 和 Model 之間的同步工做徹底是自動的,無需人爲干涉,所以開發者只需關注業務邏輯,不須要手動操做DOM, 不須要關注數據狀態的同步問題,複雜的數據狀態維護徹底由 MVVM 來統一管理。vue

clipboard.png

注意, MVVM模型中, Model和View是不會直接鏈接的,而ViewModel則會以雙向鏈接的形式鏈接Model和View。面試

0. Vue的特性(優缺點)以及和其餘框架的對比

Vue的優勢

  1. 輕量級的框架
  2. 雙向數據綁定
  3. 指令
  4. 插件化

與React的對比

節選自 Vue的官方文檔,筆者我進行了一些梳理,想了解得具體些的話仍是猛戳連接吧。
  • 二者具備許多的類似之處segmentfault

    • 使用 Virtual DOM
    • 提供了響應式 (Reactive) 和組件化 (Composable) 的視圖組件。
    • 將注意力集中保持在覈心庫,而將其餘功能如路由和全局狀態管理交給相關的庫。
  • Vue與React的不一樣之處後端

    • 組件的重渲染 React中組件的重渲染須要經過shouldComponentUpdate來避免沒必要要的子組件的重渲染,而Vue中組件的依賴是在渲染過程當中自動追蹤的,因此係統能精確知曉哪一個組件確實須要被重渲染。
    • JSX vs Template 在 React 中,全部的組件的渲染功能都依靠 JSX。JSX 是使用 XML 語法編寫 JavaScript 的一種語法糖。Vue默認推薦使用Vue模板(更適用於表現類),但Vue也支持JSX。
    • 組件做用域的CSS 在React中,CSS 做用域是經過 CSS-in-JS 的方案實現的 (好比 styled-components、glamorous 和 emotion),而Vue則有更好的解決方案,以下:瀏覽器

      <style scoped>
        @media (min-width: 250px) {
          .list-container:hover {
            background: orange;
          }
        }
      </style>

      這個可選 scoped 屬性會自動添加一個惟一的屬性 (好比 data-v-21e5b78) 爲組件內 CSS 指定做用域,編譯的時候 .list-container:hover 會被編譯成相似 .list-container[data-v-21e5b78]:hover,這樣就能夠控制CSS只在這個組件內生效。緩存

1. Vue的生命週期

具體能夠參照官網的這張圖,左側以紅色框表示的都是階段安全

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdated
  6. updated
  7. beforeDestroy
  8. destroyed

大體過程就是網絡

  • 數據初始化(1~2)
    完成數據觀測、屬性和方法的運算加載,event/wather時間回調。
  • dom掛載階段(3~4)
    el被新建立的vm.$el替換並掛載到實例上去,以後調用鉤子函數。
  • 數據更新階段(5~6)
    數據更新,虛擬dom重渲染
  • 組件卸載階段(7~8)
    銷燬實例及子實例

2. Vue實現數據雙向綁定的原理

vue實現數據雙向綁定主要是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來做爲它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉爲 getter/setter。用戶看不到 getter/setter,可是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。

vue的數據雙向綁定 將MVVM做爲數據綁定的入口,整合Observer,Compile和Watcher三者,經過Observer來監聽本身的model的數據變化,經過Compile來解析編譯模板指令,最終利用watcher搭起observer和Compile之間的通訊橋樑,達到數據變化 —>視圖更新;視圖交互變化(input)—>數據model變動雙向綁定效果。

3. Vue的路由實現

路由的實現有兩種:hash和history interface來實現前端路由,
hash在瀏覽器中符號「#」,#以及#後面的字符稱之爲hash,用window.location.hash讀取;特色:

(1)hash雖然在URL中,但不被包括在HTTP請求中

(2)用來指導瀏覽器動做,對服務端安全無用,hash不會重加載頁面

history採用h5的新特性;且提供了兩個新方法:pushState(),replaceState()能夠對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變動,不過history有個問題是:若是用戶直接在地址欄中輸入並回車,瀏覽器重啓或從新加載時,history模式會將url修改的和正常請求後端同樣,此狀況下,從新向後端發送請求,後端若是沒有配置對應路由處理,則返回404,解決方法是後端配置一下。

4. Vue的路由傳參

<router-link :to="{path:'/index',params:{id:num}}">
<router-link :to="{ path:'/index' , query:{id:num}}">

而後經過$route.params來讀取數據,但路由傳遞參數值是對象的話就不行了會報錯,傳遞前用base64轉譯一下就能夠了。

5. Vue組件間的參數傳遞

父組件與子組件傳值

父組件經過標籤上面定義傳值

<parent>
<child :child-msg="msg"></child>  //這裏必需要用 - 代替駝峯
</parent>

data(){
   return {
       msg: [1,2,3]
   };
}

子組件經過props方法接受數據

子組件經過props來接收數據: 
方式1:
props: ['childMsg']

方式2 :
props: {
    childMsg: Array //這樣能夠指定傳入的類型,若是類型不對,會警告
}

方式3:
props: {
    childMsg: {
        type: Array,    //傳入的類型
        default: [0,0,0] //這樣能夠指定默認的值
    }
}

子組件向父組件傳遞數據

子組件經過$emit方法傳遞參數

<template>
    <div @click="testClick"></div>
</template>

methods: {
    testClick() {
        this.$emit('test','123'); 
        //$emit(even,value)even 是一個函數,value 是傳給父組件的值 , 觸發名爲test方法, '123'爲向父組件傳遞的數據
    }
}

父組件經過v-on(簡寫爲@)來監聽DOM事件,並在觸發時接收數據運行js函數。

<div>
    <child @test="change" :msg="msg"></child>  //監聽子組件觸發的test事件,而後調用change方法
</div>
methods: {
    change(val) {
        this.msg = val;  // val: 123
    }
}

非父子組件間的數據傳遞

若是2個組件不是父子組件那麼如何通訊呢?這時能夠經過eventHub來實現通訊.
所謂eventHub就是建立一個事件中心,至關於中轉站,能夠用它來傳遞事件和接收事件.

let Hub = new Vue(); //建立事件中心

組件1觸發:

<div @click="eve"></div>
methods: {
    eve() {
        Hub.$emit('change','hehe'); //Hub觸發事件
    }
}

組件2接收:

<div></div>
created() {
    Hub.$on('change', () => { //Hub接收事件
        this.msg = 'hehe';
    });
}

6. Vue響應數據變化的幾種作法

  1. methods: 每次獲取都會從新計算求值
  2. computed(計算屬性,有緩存): 基於數據依賴進行緩存,只有當數據變化時,纔會從新求值。(計算屬性只有 getter,能夠在須要的時候本身設定 setter)。computed 擅長處理的情景:一個數據受多個數據影響。
  3. watch: 當須要在數據變化時執行異步操做或者消耗較大的操做時,比較有效。watch 擅長處理的情景:一個數據影響多個數據。
  4. v-model: 基於數據雙向綁定(對於 v-for 循環列表中的項,須要使用鍵值)

7. Vue的條件渲染

Vue的條件渲染涉及到兩個不一樣的關鍵字 v-ifv-show

v-if

v-if 是真正的條件渲染,它會適當地銷燬和重建DOM達到讓元素顯示和隱藏的效果。
(Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染,能夠看一下第二段程序)
v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

Vue 爲你提供了一種方式來表達「這兩個元素是徹底獨立的,不要複用它們」。
只需添加一個具備惟一值的 key 屬性便可,沒有 key 說明的話就會被複用:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

注意,<label> 元素仍然會被高效地複用,由於它們沒有添加 key 屬性。

v-show

經過修改元素的display的CSS屬性讓其顯示或者隱藏,元素始終會被渲染並保留在DOM中。

<h1 v-show="ok">Hello!</h1>
//ok 在data裏進行賦值爲true或者false

v-if vs v-show

通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。

歡迎諸位同道們留言補充ヾ(◍°∇°◍)ノ゙

參考連接
Vue官方教程
MVVM - 廖雪峯的官方網站
MVC,MVP 和 MVVM 的圖示 - 阮一峯的網絡日誌
vue.js學習筆記(一):什麼是mvvm框架,vue.js的核心思想 - _林沖 - 博客園
vue父子組件通訊 - Hi-Sen - 博客園
Vue 成長之路(一) - 媛媛碼農成長記 - SegmentFault 思否
相關文章
相關標籤/搜索