v-show 與 v-if 區別前端
第一題應該是最簡單的,提這個問題,也是想讓候選人不那麼緊張,由於但凡用過 Vue.js,多少知道 v-show 和 v-if 的區別,不然就沒得聊了。不過這最簡單的一道題,有三個層次,我會逐一追問。首先,基本全部人都會說到:
最後,若是你們若是在自學遇到困難,想找一個前端的學習環境,能夠加入咱們的前端學習圈,點擊我加入吧,會節約不少時間,減小不少在學習中遇到的難題。面試
v-show 只是 CSS 級別的 display: none; 和 display: block; 之間的切換,而 v-if 決定是否會選擇代碼塊的內容(或組件)。編程
回答這些,已經能夠獲得 50 分了,緊接着我會追問,何時用 v-show,何時用 v-if ?到這裏一部分人會比較吞吐,多是知道,但表達不出來。我比較傾向的回答是:數組
頻繁操做時,使用 v-show,一次性渲染完的,使用 v-if,只要意思對就好。緩存
第二問能夠獲得 80 分了,最後一問不多有人能答上:那使用 v-if 在性能優化上有什麼經驗?這是一個加分項,要對 Vue.js 的組件編譯有必定的理解。說一下指望的答案:性能優化
由於當 v-if="false" 時,內部組件是不會渲染的,因此在特定條件才渲染部分組件(或內容)時,能夠先將條件設置爲 false,須要時(或異步,好比 $nextTick)再設置爲 true,這樣能夠優先渲染重要的其它內容,合理利用,能夠進行性能優化。架構
綁定 class 的數組用法異步
動態綁定 class 應該不陌生吧,這也是最基本的,可是這個問題卻有點繞,什麼叫綁定 class 的數組用法?咱們看一下,最經常使用的綁定 class 怎麼寫:ide
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
綁定 class 的對象用法能知足大部分業務需求,不過,在複雜的場景下,會用到數組,來看示例:函數
<template>
<div :class="classes"></div>
</template>
<script>
export default {
computed: {
classes () {
return [${prefixCls}
,${prefixCls}-${this.type}
,
{
}
];
}
}
}
</script>
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
示例來自 iView 的 Button 組件,能夠看到,數組裏,能夠是固定的值,還有動態值(對象)的混合。
計算屬性和 watch 的區別
回答該題前,通常都會思考一下。不少人會偏題,直接去答計算屬性和 watch 怎麼用,這是不得分的,由於題目是問區別,並非用法。
計算屬性是自動監聽依賴值的變化,從而動態返回內容,監聽是一個過程,在監聽的值變化時,能夠觸發一個回調,並作一些事情。
因此區別來源於用法,只是須要動態值,那就用計算屬性;須要知道值的改變後執行業務邏輯,才用 watch,用反或混用雖然可行,但都是不正確的用法。
這個問題會延伸出幾個問題:
computed 是一個對象時,它有哪些選項?
computed 和 methods 有什麼區別?
computed 是否能依賴其它組件的數據?
watch 是一個對象時,它有哪些選項?
問題 1,有 get 和 set 兩個選項。
問題 2,methods 是一個方法,它能夠接受參數,而 computed 不能;computed 是能夠緩存的,methods 不會;通常在 v-for 裏,須要根據當前項動態綁定值時,只能用 methods 而不能用 computed,由於 computed 不能傳參。
問題 3,computed 能夠依賴其它 computed,甚至是其它組件的 data。
問題 4,有如下經常使用的配置:
handler 執行的函數
deep 是否深度
immediate 是否當即執行
事件修飾符
這個問題我會先寫一段代碼:
<custom-component>內容</custom-component>
而後問:怎樣給這個自定義組件 custom-component 綁定一個原生的 click 事件?
我一開始並不會問什麼是事件修飾符,可是若是候選人說 <custom-component @click="xxx">,就已經錯了,說明它對這個沒有概念。這裏的 @click 是自定義事件 click,並非原生事件 click。綁定原生的 click 是這樣的:
<custom-component @click.native="xxx">內容</custom-component>
該問題會引伸不少,好比常見的事件修飾符有哪些?若是你能說上 .exact,說明你是個很愛探索的人,會大大加分哦。
.exact 是 Vue.js 2.5.0 新加的,它容許你控制由精確的系統修飾符組合觸發的事件,好比:
<!-- 即便 Alt 或 Shift 被一同按下時也會觸發 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button @click.exact="onClick">A</button>
你可能還須要瞭解經常使用的幾個事件修飾符:
.stop
.prevent
.capture
.self
並且,事件修飾符在連用時,是有前後順序的。
組件中 data 爲何是函數
爲何組件中的 data 必須是一個函數,而後 return 一個對象,而 new Vue 實例裏,data 能夠直接是一個對象?
由於組件是用來複用的,JS 裏對象是引用關係,這樣做用域沒有隔離,而 new Vue 的實例,是不會被複用的,所以不存在引用對象的問題。
keep-alive 的理解
這是個概念題,主要考察候選人是否知道這個用法。簡單說,就是把一個組件的編譯緩存起來。
遞歸組件的要求
回答這道題,首先你得知道什麼是遞歸組件。而不到 10% 的人知道遞歸組件。其實在實際業務中用的確實很少,在獨立組件中會常用,遞歸組件的要求是什麼?主要有兩個:
要給組件設置 name;
要有一個明確的結束條件。
自定義組件的語法糖 v-model 是怎樣實現的
這裏的 v-model,並非給普通輸入框 <input /> 用的那種 v-model,而是在自定義組件上使用。既然是語法糖,就可以還原,咱們先還原一下:
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
這個組件中,只有一個 props,可是名字叫 value,內部還有一個 currentValue,當改變 currentValue 時,會觸發一個自定義事件 @input,並把 currentValue 的值返回。這就是一個 v-model 的語法糖,它要求 props 有一個叫 value 的項,同時觸發的自定義事件必須叫 input。這樣就能夠在自定義組件上用 v-model 了:
<custom-component v-model="value"></custom-component>
若是你能說到 model 選項,絕對是加分的。
Vuex 中 mutations 和 actions 的區別
主要的區別是,actions 能夠執行異步。actions 是調用 mutations,而 mutations 來修改 store。
Render 函數
這是比較難的一題了,由於不多有人會去了解 Vue.js 的 Render 函數,由於基本用不到。遇到這個問題,通常能夠從這幾個方面來回答:
什麼是 Render 函數,它的使用場景是什麼。
createElement 是什麼?
Render 函數有哪些經常使用的參數?
說到 Render 函數,就要說到虛擬 DOM(Virtual DOM),Virtual DOM 並非真正意義上的 DOM,而是一個輕量級的 JavaScript 對象,在狀態發生變化時,Virtual DOM 會進行 Diff 運算,來更新只須要被替換的 DOM,而不是所有重繪。
它的使用場景,就是徹底發揮 JavaScript 的編程能力,有時須要結合 JSX 來使用。
createElement 是 Render 函數的核心,它構成了 Vue Virtual DOM 的模板,它有 3 個參數:
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
經常使用的參數,主要是指上面第二個參數裏的值了,這個比較多,得去看 Vue.js 的文檔。
怎樣理解單向數據流
這個概念出如今組件通訊。父組件是經過 prop 把數據傳遞到子組件的,可是這個 prop 只能由父組件修改,子組件不能修改,不然會報錯。子組件想修改時,只能經過 $emit 派發一個自定義事件,父組件接收到後,由父組件修改。
通常來講,對於子組件想要更改父組件狀態的場景,能夠有兩種方案:
在子組件的 data 中拷貝一份 prop,data 是能夠修改的,但 prop 不能:
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
2.若是是對 prop 值的轉換,可使用計算屬性:
前端面試:專一Vue.js常見的問題答疑,掌握了基本上Vue就過關了
若是你能提到 v-model 實現數據的雙向綁定、.sync 用法,會大大加分的。
生命週期
Vue.js 生命週期主要有 8 個階段:
1.建立前 / 後(beforeCreate / created):在 beforeCreate 階段,Vue 實例的掛載元素 el 和數據對象 data 都爲 undefined,還未初始化。在 created 階段,Vue 實例的數據對象 data 有了,el 尚未。
2.載入前 / 後(beforeMount / mounted):在 beforeMount 階段,Vue 實例的 $el 和 data 都初始化了,但仍是掛載以前爲虛擬的 DOM 節點,data 還沒有替換。在 mounted 階段,Vue 實例掛載完成,data 成功渲染。
3.更新前 / 後(beforeUpdate / updated):當 data 變化時,會觸發 beforeUpdate 和 updated 方法。這兩個不經常使用,且不推薦使用。
4.銷燬前 / 後(beforeDestroy / destroyed):beforeDestroy 是在 Vue 實例銷燬前觸發,通常在這裏要經過 removeEventListener 解除手動綁定的事件。實例銷燬後,觸發 destroyed。
組件間通訊
這個問題看似簡單,卻比較大,回答時,能夠拆分爲幾種場景:
1、父子通訊:
父向子傳遞數據是經過 props,子向父是經過 events(emit);
經過父鏈子鏈也能夠通訊(parent / $children);
ref也能夠訪問組件實例;provide / inject API。
2、兄弟通訊:
Bus
Vuex
3、跨級通訊:
Bus;
Vuex;
provide / inject API。
除了常規的通訊方法,最近幾篇文章提到的 dispatch / broadcast 和 findComponents 系列方法也能夠說的,若是能說到這些,說明你對 Vue.js 組件已經有較深刻的研究。
路由的跳轉方式
通常有兩種:
經過 <router-link to="home">,router-link 標籤會渲染爲 標籤,在 template 中的跳轉都是用這種;
另外一種是編程式導航,也就是經過 JS 跳轉,好比 router.push('/home')。
Vue.js 2.x 雙向綁定原理
這個問題幾乎是面試必問的,回答也是有深有淺。基本上要知道核心的 API 是經過 Object.defineProperty() 來劫持各個屬性的 setter / getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調,這也是爲何 Vue.js 2.x 不支持 IE8 的緣由(IE 8 不支持此 API,且沒法經過 polyfill 實現)。
什麼是 MVVM,與 MVC 有什麼區別
MVVM 模式是由經典的軟件架構 MVC 衍生來的。當 View(視圖層)變化時,會自動更新到 ViewModel(視圖模型),反之亦然。View 和 ViewModel 之間經過雙向綁定(data-binding)創建聯繫。與 MVC 不一樣的是,它沒有 Controller 層,而是演變爲 ViewModel。
ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而 View 和 Model 之間的同步工做是由 Vue.js 完成的,咱們不須要手動操做 DOM,只須要維護好數據狀態。
感悟
事物由簡單到複雜再到簡單,技術無止盡,接觸的越多,感受本身知道的越少。所謂的心存敬畏吧,共勉!