Vue面試題以及實(shí)際項(xiàng)目中遇到的坑

之前有提到,在經(jīng)歷了前端轉(zhuǎn)型之后,一場(chǎng)技術(shù)變革的到來(lái),小程序,h5移動(dòng)端,對(duì)性能優(yōu)化的要求越來(lái)越高,受面向?qū)ο笏枷刖幊谭绞降挠绊懀岸爽F(xiàn)在主流的技術(shù)框架就是Vue,React,Angular.他們的數(shù)據(jù)驅(qū)動(dòng)模式,MVVM模式,很受歡迎,這種spa單頁(yè)面應(yīng)用,組件思維對(duì)一個(gè)龐大的web應(yīng)用很有幫助提升加載速度,減少Dom操作,隨之而來(lái)的也就是不斷地學(xué)習(xí),對(duì)技術(shù)員的技術(shù)要求也開始偏向于vue,小程序,公眾號(hào),由于智能手機(jī)的普及,app端比網(wǎng)頁(yè)更受歡迎,所以就要不斷地學(xué)習(xí)新的知識(shí),否則會(huì)被淘汰。


好了,不說(shuō)廢話了,總結(jié)一下使用vue開發(fā)項(xiàng)目過程中遇到的坑以及面試經(jīng)驗(yàn)。

step一,談?wù)勀銓?duì)MVVM 的理解?

  • MVVM 由 Model,View,ViewModel 三部分構(gòu)成,Model 層代表數(shù)據(jù)模型,也可以在Model中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯;View 代表UI 組件,它負(fù)責(zé)將數(shù)據(jù)模型轉(zhuǎn)化成UI 展現(xiàn)出來(lái),ViewModel 是一個(gè)同步View 和 Model的對(duì)象。
    在MVVM架構(gòu)下,View 和 Model 之間并沒有直接的聯(lián)系,而是通過ViewModel進(jìn)行交互,Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會(huì)同步到Model中,而Model 數(shù)據(jù)的變化也會(huì)立即反應(yīng)到View 上。
    ViewModel 通過雙向數(shù)據(jù)綁定把 View 層和 Model 層連接了起來(lái),而View 和 Model 之間的同步工作完全是自動(dòng)的,無(wú)需人為干涉,因此開發(fā)者只需關(guān)注業(yè)務(wù)邏輯,不需要手動(dòng)操作DOM, 不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題,復(fù)雜的數(shù)據(jù)狀態(tài)維護(hù)完全由 MVVM 來(lái)統(tǒng)一管理。

step二,vue路由傳參的方式

[圖片上傳失敗...(image-f2dfe1-1554273574051)]

step三,vue組件之間的傳參

[圖片上傳失敗...(image-901dae-1554273574051)]

step四,vue-router有哪幾種導(dǎo)航鉤子?

答案

  • 第一種是全局導(dǎo)航鉤子(全局守衛(wèi)):router.beforeEach(to,from,next),作用:跳轉(zhuǎn)前進(jìn)行判斷攔截。
  • 第 二種:全局解析守衛(wèi)router.beforeResolve,在導(dǎo)航被確認(rèn)前,所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被調(diào)用。(2.5.0新增)。
  • 第三種:?jiǎn)为?dú)路由獨(dú)享的守衛(wèi)beforeEnter,在路由配置時(shí)定義,與全局守衛(wèi)的方法是一樣的。
  • 第四種:組件內(nèi)的守衛(wèi)。直接在路由組件內(nèi)定義守衛(wèi),
    以下為官網(wǎng)文檔的介紹:
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
    // 不!能!獲取組件實(shí)例 `this`
    // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建
  },
  beforeRouteUpdate (to, from, next) {
    // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
    // 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候,
    // 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
    // 可以訪問組件實(shí)例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
    // 可以訪問組件實(shí)例 `this`
  }

step五,請(qǐng)寫出幾種常用的vue指令

v-class、v-for、v-if、v-show、v-on,v-model

step六,請(qǐng)?jiān)敿?xì)解釋一下vue(2.0)的生命周期?

答案:

生命周期 階段 描述
beforeCreated 創(chuàng)建前 vue實(shí)例的掛載元素$el和數(shù)據(jù)對(duì)象data都為undefined,還未初始化。
created 創(chuàng)建后 vue實(shí)例的數(shù)據(jù)對(duì)象data有了,$el還沒有。
beforeMount 模板載入前 vue實(shí)例的$el和data都初始化了,但還是掛載之前為虛擬的dom節(jié)點(diǎn),data.message還未替換
mounted 模板載入后 vue實(shí)例掛載完成,data.message成功渲染。
beforeUpdate 組件更新前 組件更新之前調(diào)用
updated 組件更新后 組件更新之后調(diào)用
beforeDestroy 組件銷毀前 調(diào)用$destroy方法后,立即執(zhí)行beforeDestroy
pdestroyed 組件銷毀后 組件銷毀后調(diào)用,此時(shí)只剩下dom空殼

step七,slot是什么?并說(shuō)一下詳細(xì)的用法?

答案:
vue官網(wǎng)解釋:slot 插槽,-------(Vue 實(shí)現(xiàn)了一套內(nèi)容分發(fā)的 API,這套 API 基于當(dāng)前的 Web Components 規(guī)范草案,將 <slot> 元素作為承載分發(fā)內(nèi)容的出口。
)是不是看完稀里糊涂的,反正我是稀里糊涂的,再來(lái)說(shuō)說(shuō)我自己的理解:
slot就是為了實(shí)現(xiàn)真正的靈活的單頁(yè)組件,在組件外部靈活控制組件內(nèi)部的內(nèi)容一種形式或者是入口,就是將組件內(nèi)所需要的內(nèi)容以插槽(slot)的形式插入到公共組件中,以達(dá)到靈活控制。
當(dāng)組件渲染的時(shí)候,這個(gè) <slot> 元素將會(huì)被替換為“Your Profile”。插槽內(nèi)可以包含任何模板代碼,包括 HTML:詳情請(qǐng)看vue 帶動(dòng)畫效果的NavBar這里邊有詳細(xì)介紹到<slot>的使用方法。

step八,談?wù)勀銓?duì)vue響應(yīng)式原理的理解?

答案:
先看看官網(wǎng)的解釋:
當(dāng)你把一個(gè)普通的 JavaScript 對(duì)象傳給 Vue 實(shí)例的 data 選項(xiàng),Vue 將遍歷此對(duì)象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter。Object.defineProperty 是 ES5 中一個(gè)無(wú)法 shim 的特性,這也就是為什么 Vue 不支持 IE8 以及更低版本瀏覽器的原因。

這些 getter/setter 對(duì)用戶來(lái)說(shuō)是不可見的,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時(shí)通知變化。這里需要注意的問題是瀏覽器控制臺(tái)在打印數(shù)據(jù)對(duì)象時(shí) getter/setter 的格式化并不同,所以你可能需要安裝 vue-devtools 來(lái)獲取更加友好的檢查接口。

每個(gè)組件實(shí)例都有相應(yīng)的 watcher 實(shí)例對(duì)象,它會(huì)在組件渲染的過程中把屬性記錄為依賴,之后當(dāng)依賴項(xiàng)的 setter 被調(diào)用時(shí),會(huì)通知 watcher 重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新。

step九,直接對(duì)對(duì)象屬性進(jìn)行添加和刪除會(huì)不會(huì)直接響應(yīng)到視圖中?也就是說(shuō)數(shù)組的更新方法?并說(shuō)明原因?

答案:
直接對(duì)對(duì)象屬性進(jìn)行添加和刪除是不會(huì)響應(yīng)到視圖中的,需要用到this.$set()方法
舉個(gè)例子

var vm = new Vue({
  data:{
      myjson:{
    name:"張三"     
}
  }
})
vm.myjson.age= "12";    //這樣直接對(duì)對(duì)象屬性進(jìn)行增加是不會(huì)直接響應(yīng)到視圖中的。
需要這么寫:
this.$set(this.myjson,'age',12);//才會(huì)生效

原因
受現(xiàn)代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測(cè)到對(duì)象屬性的添加或刪除。由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì)屬性執(zhí)行 getter/setter 轉(zhuǎn)化過程,所以屬性必須在 data 對(duì)象上存在才能讓 Vue 轉(zhuǎn)換它,這樣才能讓它是響應(yīng)的。

step十,如何創(chuàng)建一個(gè)公共的全局組件,并在每個(gè)頁(yè)面中調(diào)用以及如何創(chuàng)建并調(diào)用公共的方法?

答案:
[圖片上傳失敗...(image-a84d49-1554273574050)]

將創(chuàng)建好的組件或者js方法導(dǎo)出并掛載到vue實(shí)例上。
詳情請(qǐng)參考關(guān)于vue全局引用公共的js和公共的組件的折騰

step十一,請(qǐng)說(shuō)明v-ifv-show的異同?

同:兩者都是達(dá)到顯示隱藏的功能
異:

  • v-if指令是直接銷毀和重建DOM達(dá)到讓元素顯示和隱藏的效果
  • v-show指令通過修改元素的display屬性讓其顯示或者隱藏

step十二,<keep-alive></keep-alive>的作用是什么?

答案:
<keep-alive></keep-alive> 包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,主要用于保留組件狀態(tài)或避免重新渲染。
用自己的理解說(shuō)
比如有一個(gè)列表和一個(gè)詳情,那么用戶就會(huì)經(jīng)常執(zhí)行打開詳情=>返回列表=>打開詳情…這樣的話列表和詳情都是一個(gè)頻率很高的頁(yè)面,那么就可以對(duì)列表組件使用<keep-alive></keep-alive>進(jìn)行緩存,這樣用戶每次返回列表的時(shí)候,都能從緩存中快速渲染,而不是重新渲染,這樣就會(huì)減輕服務(wù)器壓力,提高性能。

step十三,<router-link>屬性以及方法?

答案:

  • :to 相當(dāng)于a標(biāo)簽中的"herf"屬性,后面跟跳轉(zhuǎn)鏈接所用 ,會(huì)渲染成a標(biāo)簽--<a href="url">
<router-link :to="/home">Home</router-link>
<!-- 渲染結(jié)果 -->
<a href="/home">Home</a>

  • replace屬性,加上該屬性頁(yè)面切換不會(huì)留下歷史紀(jì)錄。
<router-link :to="/home" replace></router-link>

  • tag屬性,具有tag屬性的router-link會(huì)被渲染成相應(yīng)的標(biāo)簽
<router-link :to="/home" tag="li">Home</router-link>
<!-- 渲染結(jié)果 -->
<li>Home</li>
此時(shí)頁(yè)面的li同樣會(huì)起到a鏈接跳轉(zhuǎn)的結(jié)果,vue會(huì)自動(dòng)為其綁定點(diǎn)擊事件,并跳轉(zhuǎn)頁(yè)面

  • active-class屬性:設(shè)置鏈接激活時(shí)的class屬性:默認(rèn)值為router-link-active,所以如果沒有設(shè)置,就會(huì)被渲染為這個(gè)class,我們可以在router.js里邊配置這個(gè)屬性
const router = new VueRouter({
  mode: 'hash',
  linkActiveClass: 'u-link--Active', // 這是鏈接激活時(shí)的class
})
<router-link :to="/home" active-class="u-link--Active">Home</router-link>

  • exact屬性:嚴(yán)格模式
// 這個(gè)鏈接只會(huì)在地址為 / 的時(shí)候被激活 
<router-link to="/" exact>Home</router-link>

<router-link to="/user">USER</router-link>

<router-link to="/user/userinfo">USER-info</router-link>

// 如果不設(shè)置exact,則當(dāng)路由到了/user/userinfo 頁(yè)面時(shí),USER也是被設(shè)置了router-link-active樣式的!

  • 方法:
 router-link默認(rèn)是觸發(fā)router.push(location),如果設(shè)置的replace 則觸發(fā)router.replace(location),這有啥區(qū)別呢?
  router.push() :導(dǎo)航跑到不同的URL,這個(gè)方法會(huì)向history棧添加一個(gè)新的記錄,所以,當(dāng)用戶點(diǎn)擊瀏覽器后退按鈕時(shí),則回到之前的url.
  router.replace(): 跟router.push作用是一樣的,但是,它不會(huì)向history添加新記錄,而是跟它的方法名一樣替換掉當(dāng)前的history記錄.
  router.go(n): 這個(gè)方法的參數(shù)是一個(gè)整數(shù),意思是在history記錄中向前或者后退多少步,類似window.history.go(n)

step十四,v-once的作用和用法?

只渲染元素和組件一次,隨后的渲染,使用了此指令的元素/組件及其所有的子節(jié)點(diǎn),都會(huì)當(dāng)作靜態(tài)內(nèi)容并跳過,這可以用于優(yōu)化更新性能。
舉個(gè)例子:一看便知

<template>
  <div>
    <div>{{count}}</div>
    <button v-on:click="addCount">改變count的值</button>
  </div>
</template>
<script>
  export default {
    name: "VueOnce",
    data() {
      return {
        count: "我是不可改變的"
      }
    },
    methods: {
      addCount: function () {
        this.count = "我就要改變你";
       此時(shí)這個(gè)操作dom里邊的count是不會(huì)變化的
      }
    }
  }
</script>
<style scoped>
</style>

step十五,如何解決在加載頁(yè)面時(shí)出現(xiàn)的閃爍問題。

v-cloak詳情請(qǐng)移步v-cloak詳解

step十六,vue如何兼容ie的問題。

答案:
回答關(guān)鍵字 - babel-polyfill插件
詳情請(qǐng)移步vue-cli 解決ie兼容性問題

step十七,vue-cli如何解決跨域?

答案:常見的后臺(tái)加請(qǐng)求頭以及jsonp就不詳細(xì)解釋了,若要看詳細(xì)教程請(qǐng)移步前端面試題總結(jié)
這里主要介紹的是 npm模塊之http-proxy-middleware的解決跨域的辦法。詳情移步vue-cli如何解決跨域

作者:愿醒靜臥忘塵谷
鏈接:http://www.lxweimin.com/p/42a4be57287f
來(lái)源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 寫在前面 之前有提到,在經(jīng)歷了前端轉(zhuǎn)型之后,一場(chǎng)技術(shù)變革的到來(lái),小程序,h5移動(dòng)端,對(duì)性能優(yōu)化的要求越來(lái)越高,受面...
    郝艷峰Vip閱讀 30,805評(píng)論 4 48
  • VUE Vue :數(shù)據(jù)驅(qū)動(dòng)的M V Vm框架 m :model(后臺(tái)提供數(shù)據(jù)),v :view(頁(yè)面),vM(模板...
    wudongyu閱讀 5,424評(píng)論 0 11
  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包就 是將函數(shù)內(nèi)部和函數(shù)外...
    xuguibin閱讀 9,725評(píng)論 1 52
  • Vue八個(gè)生命周期 beforeCreate【創(chuàng)建前】created【創(chuàng)建后】 beforeMount【載入前】 ...
    艾薩克菊花閱讀 1,343評(píng)論 0 12
  • 1、V-if和V-show的區(qū)別 答案:區(qū)別就是dom元素是否掛載了,v-show是dom樹上有內(nèi)容,不顯示,di...
    cj_jax閱讀 20,180評(píng)論 2 22