Vue.js 面試題整理

會飛的Tiger發表於2019-06-28

Vue專案結構介紹

  • build 資料夾:用於存放 webpack 相關配置和指令碼。
  • config 資料夾:主要存放配置檔案,比如配置開發環境的埠號、開啟熱載入或開啟gzip壓縮等。
  • dist 資料夾:預設命令打包生成的靜態資原始檔。
  • node_modules:存放 npm 命令下載的開發環境和生產環境的依賴包。
  • src: 存放專案原始碼及需要引用的資原始檔。
  • src下assets:存放專案中需要用到的資原始檔,css、js、images 等。
  • src下componets:存放 vue 開發中一些公共元件。
  • src下emit:自己配置的 vue 集中式事件管理機制。
  • src下router:vue-router vue 路由的配置檔案。
  • src下service:自己配置的 vue 請求後臺介面方法。
  • src下page:存在 vue頁面元件的資料夾。
  • src下util:存放 vue開發過程中一些公共的 js 方法。
  • src下vuex:存放 vuex 為vue專門開發的狀態管理器。
  • src下app.vue:整個工程的 vue 根元件。
  • src下main.js:工程的入口檔案。
  • index.html:設定專案的一些meta頭資訊和提供html元素節點,用於掛載 vue。
  • package.json:對專案的描述以及對專案部署和啟動、打包的 npm 命令管理。

Vue 常用指令

  • v-model 多用於表單元素實現雙向資料繫結(同angular中的ng-model)
  • v-for 格式: v-for="欄位名 in(of) 陣列json" 迴圈陣列或json(同angular中的ng-repeat),需要注意從vue2開始取消了$index
  • v-show 顯示內容 (同angular中的ng-show)
  • v-hide 隱藏內容(同angular中的ng-hide)
  • v-if 顯示與隱藏 (dom元素的刪除新增 同angular中的ng-if 預設值為false)
  • v-else-if 必須和v-if連用
  • v-else 必須和v-if連用 不能單獨使用 否則報錯 模板編譯錯誤
  • v-bind 動態繫結 作用: 及時對頁面的資料進行更改
  • v-on:click 給標籤繫結函式,可以縮寫為@,例如繫結一個點選函式 函式必須寫在methods裡面
  • v-text 解析文字
  • v-html 解析html標籤
  • v-bind:class 三種繫結方法 1、物件型 '{red:isred}' 2、三元型 'isred?"red":"blue"' 3、陣列型 '[{red:"isred"},{blue:"isblue"}]'
  • v-once 進入頁面時 只渲染一次 不在進行渲染
  • v-cloak 防止閃爍
  • v-pre 把標籤內部的元素原位輸出

v-for 與 v-if 的優先順序

當它們處於同一節點,v-for 的優先順序比 v-if 更高。

vue中 keep-alive 元件的作用

keep-alive:主要用於保留元件狀態或避免重新渲染。兩個重要屬性,include 快取元件名稱,exclude 不需要快取的元件名稱。

v-if 和 v-show 有什麼區別

共同點:

v-if 和 v-show 都可以用來動態顯示DOM元素。

區別:

  • 編譯過程: v-if 是真正的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子元件適當地被銷燬和重建。v-show 的元素始終會被渲染並保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。
  • 編譯條件: v-if 是惰性的,如果在初始渲染時條件為假,則什麼也不做。直到條件第一次變為真時,才會開始渲染條件塊。v-show 不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
  • 效能消耗: v-if有更高的切換消耗。v-show 有更高的初始渲染消耗。
  • 應用場景: v-if適合執行時條件很少改變時使用。v-show 適合頻繁切換。

v-on 可以監聽多個方法嗎?

v-on 可以監聽多個方法,但是同一種事件型別的方法,v-on 只能監聽一個。

vue 中 key 值的作用

用於 管理可複用的元素。因為Vue 會盡可能高效地渲染元素,通常會複用已有元素而不是從頭開始渲染。當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它預設用“就地複用”策略。如果資料項的順序被改變,Vue 將不會移動 DOM 元素來匹配資料項的順序, 而是簡單複用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每個元素。key的作用主要是為了高效的更新虛擬DOM

vue $nextTick 作用是什麼?

官方解釋:在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後立即使用這個方法,獲取更新後的 DOM。簡單的說就是再DOM操作時,vue的更新是非同步的,$nextTick 是用來知道什麼時候 DOM 更新完成的。
舉例:我們給一個div設定顯示隱藏,當點選 button 的時候 #textDiv 先是被渲染出來,接著我們獲取 #textDiv 的 html內容

<div id="app">
    <div id="textDiv" v-if="isShow">這是一段文字</div>
    <button @click="getText">獲取div內容</button>
</div>
<script>
var app = new Vue({
    el : "#app",
    data:{
        isShow: false
    },
    methods:{
        getText:function(){
            this.isShow= true;
            var text = document.getElementById('textDiv').innnerHTML;
             console.log(text);
        }
    }
})
</script>

這段程式碼表面上看不會有問題,但實際上點選報錯,提示獲取不到div元素,這裡就涉及到 Vue 非同步更新佇列。

Vue非同步更新佇列

Vue 執行 DOM 更新時,只要觀察到資料變化,就會自動開啟一個佇列,並緩衝在同一個事件迴圈中發生的所以資料改變。在緩衝時會去除重複資料,從而避免不必要的計算和 DOM 操作。以上面的程式碼舉例,你用一個 for 迴圈來動態改變 isShow 100 次,其實它只會應用最後一次改變,如果沒有這種機制,DOM 就要重繪 100 次,這固然是一個很大的開銷。所以執行 this.isShow= true時,#textDiv 還沒有被建立出來,直到下一個 Vue 事件迴圈時,才開始建立。
上面的程式碼應修改為:

getText:function(){
    this.showDiv = true;
    this.$nextTick(function(){
            var text = document.getElementById('div').innnerHTML;
            console.log(text);  
    });
}

Vue 如何註冊元件

元件系統是Vue.js其中一個重要的概念,它提供了一種抽象,讓我們可以使用獨立可複用的小元件來構建大型應用,任意型別的應用介面都可以抽象為一個元件樹

全域性註冊

  • 在 src 資料夾中新建 utils 資料夾,在 utils 資料夾中新建 components.js 檔案
  • 在 components.js 檔案引入所有要註冊的全域性元件
  • 在 main.js 中引入 components.js 檔案並使用 Vue.use() 全域性註冊
    舉例:

元件 diyHeader.vue

<template>
    <div>
        <div  id="header" @click="fun"></div>
    </div>
</template>

<script>
export default {
    methods:{
        fun(){
            alert(1);
        }
    }
}
</script>

<style>
#header{
    height: 100px;
    background: red;
}
</style>

util下components.js

import DiyHeader from "../components/diyHeader.vue"
export default (Vue)=>{
    Vue.component("DiyHeader", DiyHeader)
  }

main.js

import components from "./util/components"
Vue.use(components);

之後就可以直接在專案中使用 DiyHeader 這個元件

區域性註冊

在頁面裡匯入元件然後放到components中就可以使用了

import DiyHeader from "../components/diyHeader.vue"
export default {
  name: "App",
  components: { DiyHeader },
}

全域性註冊指令

  • 在 src 資料夾中新建 utils 資料夾,在 utils 資料夾中新建 directives.js 檔案
  • 在directives.js檔案引入所有要註冊的全域性指令
  • 在 main.js 中引入 directives.js 檔案並使用 Vue.use() 全域性註冊

directives.js

export default (Vue)=>{
    Vue.directive("focus", {
        inserted: function (el) {
            el.focus();
        }
    })
}

main.js

import directives from '@/utils/directives.js'
Vue.use(directives

什麼是vue生命週期和生命週期鉤子函式?

vue 的生命週期是: vue 例項從建立到銷燬,也就是從開始建立、初始化資料、編譯模板、掛載Dom→渲染、更新→渲染、解除安裝等一系列過程。

vue生命週期鉤子函式有哪些?

beforeCreate:

在例項初始化之後,資料觀測 (data observer) 和 event/watcher 事件配置之前被呼叫。

created:

在例項建立完成後被立即呼叫。在這一步,例項已完成以下的配置:資料觀測 (data observer), 屬性和方法的運算,watch/event 事件回撥。然而,掛載階段還沒開始,$el 屬性目前不可見。

beforeMount:

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

mounted:

el 被新建立的 vm.$el 替換,並掛載到例項上去之後呼叫該鉤子。如果 root 例項掛載了一個文件內元素,當 mounted 被呼叫時 vm.$el 也在文件內。

beforeUpdate:

資料更新時呼叫,發生在虛擬 DOM 打補丁之前。這裡適合在更新之前訪問現有的 DOM,比如手動移除已新增的事件監聽器。該鉤子在伺服器端渲染期間不被呼叫,因為只有初次渲染會在服務端進行。

updated:

由於資料更改導致的虛擬 DOM 重新渲染和打補丁,在這之後會呼叫該鉤子。

activated

keep-alive 元件啟用時呼叫。該鉤子在伺服器端渲染期間不被呼叫。

deactivated

keep-alive 元件停用時呼叫。該鉤子在伺服器端渲染期間不被呼叫。

beforeDestroy

例項銷燬之前呼叫。在這一步,例項仍然完全可用。該鉤子在伺服器端渲染期間不被呼叫。

destroyed

Vue 例項銷燬後呼叫。呼叫後,Vue 例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。該鉤子在伺服器端渲染期間不被呼叫。

errorCaptured(2.5.0+ 新增)

當捕獲一個來自子孫元件的錯誤時被呼叫。此鉤子會收到三個引數:錯誤物件、發生錯誤的元件例項以及一個包含錯誤來源資訊的字串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。

vue等單頁面應用及其優缺點

單頁Web應用:

就是隻有一張Web頁面的應用。單頁應用程式 (SPA) 是載入單個 HTML 頁面並在使用者與應用程式互動時動態更新該頁面的 Web 應用程式。瀏覽器一開始會載入必需的 HTML、CSS 和 JavaScript,所有的操作都在這張頁面上完成,都由 JavaScript 來控制。因此,對單頁應用來說模組化的開發和設計顯得相當重要。

單頁 Web 應用的優點:

  • 提供了更加吸引人的使用者體驗:具有桌面應用的即時性、網站的可移植性和可訪問性。
  • 單頁應用的內容的改變不需要重新載入整個頁面,web應用更具響應性和更令人著迷。
  • 單頁應用沒有頁面之間的切換,就不會出現“白屏現象”,也不會出現假死並有“閃爍”現象
  • 單頁應用相對伺服器壓力小,伺服器只用出資料就可以,不用管展示邏輯和頁面合成,吞吐能力會提高几倍。
  • 良好的前後端分離。後端不再負責模板渲染、輸出頁面工作,後端API通用化,即同一套後端程式程式碼,不用修改就可以用於Web介面、手機、平板等多種客戶端。

單頁 Web 應用的缺點:

  • 首次載入耗時比較多。
  • SEO問題,不利於百度,360等搜尋引擎收錄。
  • 容易造成Css命名衝突。
  • 前進、後退、位址列、書籤等,都需要程式進行管理,頁面的複雜度很高,需要一定的技能水平和開發成本高。

自定義指令的幾個鉤子函式

  • bind:只呼叫一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。
  • inserted:被繫結元素插入父節點時呼叫 (僅保證父節點存在,但不一定已被插入文件中)。
  • update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新 。
  • componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。
  • unbind:只呼叫一次,指令與元素解綁時呼叫。

13. Vue雙向繫結實現的原理

採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應監聽回撥。當把一個普通 Javascript 物件傳給 Vue 例項來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉為 getter/setter。使用者看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。

active-class是哪個元件的屬性

vue-router 模組 的router-link元件

vue-router有哪幾種導航鉤子

  • 全域性守衛: router.beforeEach
  • 全域性解析守衛: router.beforeResolve
  • 全域性後置鉤子: router.afterEach
  • 路由獨享的守衛: beforeEnter
  • 元件內的守衛: beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

vuex是什麼?怎麼使用?哪種功能場景使用它?

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理器,採用集中式儲存管理應用的所有元件的狀態,主要是為了多頁面、多元件之間的通訊。
Vuex有5個重要的屬性,分別是 State、Getter、Mutation、Action、Module,由 view 層發起一個 Action 給 Mutation,在 Mutation 中修改狀態,返回新的狀態,通過 Getter暴露給 view層的元件或者頁面,頁面監測到狀態改變於是更新頁面。如果你的專案很簡單,最好不要使用 Vuex,對於大型專案,Vuex 能夠更好的幫助我們管理元件外部的狀態,一般可以運用在購物車、登入狀態、播放等場景中。

$route和$router的區別

$route是“路由資訊物件”,包括path,params,hash,query,fullPath,matched,name等路由資訊引數。而$router是“路由例項”物件包括了路由的跳轉方法,鉤子函式等

什麼是MVVM?

答:MVVM是是Model-View-ViewModel的縮寫,Model代表資料模型,定義資料操作的業務邏輯,View代表檢視層,負責將資料模型渲染到頁面上,ViewModel通過雙向繫結把View和Model進行同步互動,不需要手動操作DOM的一種設計思想。

怎麼定義vue-router的動態路由?怎麼獲取傳過來的動態引數?

答:在router目錄下的index.js檔案中,對path屬性加上/:id。 使用router物件的params.id

vue專案優化解決方案

  • 使用mini-css-extract-plugin外掛抽離css
  • 配置 optimization 把公共的js程式碼抽離出來
  • 通過 Webpack 處理檔案壓縮
  • 不打包框架、庫檔案,通過cdn的方式引入
  • 小圖片使用 base64
  • 配置專案檔案懶載入
  • UI 庫配置按需載入
  • 開啟 Gzip壓縮

Vue路由的實現

hash模式

通過用window.location.hash監聽頁面的hash值變化,切換對於的內容,hash變化不會過載頁面。

history模式

history採用HTML5的新特性;且提供了兩個新方法:pushState(),replaceState()可以對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變更。

Vue 父子元件通訊

  • 父元件向子元件傳值通過props
  • 子元件向父元件傳遞,子元件使用$emit傳遞,父元件使用on監聽。

Vue minix(混入)的用法

minix(混入) 是 Vue 中的高階用法,混入 (mixin) 提供了一種非常靈活的方式,來分發 Vue 元件中的可複用功能。比如我們做一個下拉載入,很多元件都需要用到下拉載入,我們就可以把下拉載入封裝成一個minix,然後需要下拉載入功能的頁面都去匯入這個minix,minix裡面的屬性或者方法就會被混合到當前元件本身的屬性上。簡單的說,minix B 有個 C方法(下拉載入),頁面 A 需要下拉載入於是就匯入了 minix B,這時候頁面 A 也就擁有了 C 方法。如果頁面 A 本身有個 D方法,這時頁面 A 就會既有 C 方法也有本身的 D 方法。

關於 Vue.use() 的理解

Vue.use() 是Vue的一個全域性註冊方法,主要用來註冊外掛,預設第一個引數是它接受的引數型別必須是Function或者是Object,如果是個物件,必須提供install方法,install方法預設第一個引數為 Vue,其後的引數為註冊時傳入的arguments。如果是 Function 那麼這個函式就被當做 install 方法。同一個外掛 Vue.use 會自動阻止多次註冊。除了在註冊外掛中使用 Vue.use 外,我們還可以在 directive註冊、filters註冊、components註冊等條件下使用。
有的時候我們會遇到某些時候引入外掛是並沒有使用 Vue.use ,比如使用 axios 的時候,原因是 axios 沒有 install 方法,所以也就不需要使用 Vue.use 來全域性註冊。

歡迎大家關注我的個人公眾號,網際網路碼農,專注網際網路程式設計技術分享,關注公眾號,回覆關鍵字,可以領取系列程式設計學習視訊哦,前端、java、ios、安卓、c++、python應用盡有。
Vue.js 面試題整理

相關文章