![Vue2.0復仇者聯盟之無限面試題](http://p2.ttnews.xyz/loading.gif)
大家知道Vue全家桶裡面強力成員很多,比如vue的同門師兄弟:vuex負責狀態管理,vue-router負責前端路由,devtools extension幫助開發者調試,vue-cli配置webpack模板,axios負責網絡請求,它跟vue的強力對手Angular有很大淵源,來自餓了麼的element-ui使得開發者使用Vue做項目更容易了。
而面試官一般會圍繞這些方面的問題考察面試者的vue實戰經驗。為了讓大家更有底氣地跟面試官說做過vue項目,本文跟大家一起分多篇文章將這些關於vue實戰的相關知識點一網打盡,並長期更新。
Vue相關概念
background
Vue 是 2016 年發展最為迅速的 JS 框架之一。
Vue 將自己描述為一款“用於構建直觀,快速和組件化交互式界面的 MVVM 框架”。
它於 2014 年 2 月首次由 Google 前員工 Evan You 發佈。
尤其是考慮到 Vue 在沒有大公司的支持的情況下,作為一個人開發的框架還能獲得這麼多的吸引力,這無疑是非常成功的。
尤雨溪目前有一個包含數十名核心開發者的團隊。2016 年,版本 2 發佈。Vue 被阿里巴巴,百度,Expedia,任天堂,GitLab 使用 — 可以在 madewithvuejs.com 找到一些小型項目的列表。
feature
Vue 擅長處理組件:小型的無狀態的函數接收輸入和返回元素作為輸出。
Vue 使用 Javascript ES5 或 ES6。
模板-HTML
Vue 具有“單個文件組件”。這似乎是對於關注分離的權衡 - 模板,腳本和樣式在一個文件中,但在三個不同的有序部分中。這意味著你可以獲得語法高亮,CSS 支持以及更容易使用預處理器(如 Jade 或 SCSS)
Vue 相比於Angular和React是最輕量的。
Vue.js 完美的兼顧了它將為你做什麼和你需要做什麼。(...)Vue.js 始終是可及的,一個堅固,但靈活的安全網,保證編程效率和把操作 DOM 造成的痛苦降到最低。
Vue 使用了MVVM模式,支持單向綁定和雙向綁定
Vue 的體積為23K
Vue 使用了虛擬 DOM(Virtual DOM)
Vue 學習起來很容易。公司轉向 Vue 是因為它對初級開發者來說似乎更容易一些。有了 Vue,初級和高級開發人員之間的差距縮小了,他們可以更輕鬆地協作,代碼會更簡潔,減少 bug,減少解決問題的時間。
vue的雙向數據綁定原理
vue是採用數據劫持結合發佈者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變動時發佈消息給訂閱者,觸發相應的監聽回調,達到監聽數據變動的目的。
Object.defineProperty 是 ES5 中一個無法 shim 的特性,這也就是為什麼 Vue 不支持 IE8 以及更低版本瀏覽器的原因。
這些 getter/setter 對用戶來說是不可見的,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。這裡需要注意的問題是瀏覽器控制檯在打印數據對象時 getter/setter 的格式化並不同,所以你可能需要安裝 vue-devtools 來獲取更加友好的檢查接口。
每個組件實例都有相應的 watcher 實例對象,它會在組件渲染的過程中把屬性記錄為依賴,之後當依賴項的 setter 被調用時,會通知 watcher 重新計算,從而致使它關聯的組件得以更新。
![Vue2.0復仇者聯盟之無限面試題](http://p2.ttnews.xyz/loading.gif)
檢測變化的注意事項
受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或刪除。由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。例如:
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是響應的
vm.b = 2
// `vm.b` 是非響應的
Vue 不允許在已經創建的實例上動態添加新的根級響應式屬性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法將響應屬性添加到嵌套的對象上:
Vue.set(vm.someObject, 'b', 2)
您還可以使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名:
this.$set(this.someObject,'b',2)
有時你想向已有對象上添加一些屬性,例如使用 Object.assign() 或 _.extend() 方法來添加屬性。但是,添加到對象上的新屬性不會觸發更新。在這種情況下可以創建一個新的對象,讓它包含原對象的屬性和新的屬性:
// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:
當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength
舉個例子:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的
為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果,同時也將觸發狀態更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:
vm.$set(vm.items, indexOfItem, newValue)
為了解決第二類問題,你可以使用 splice:
vm.items.splice(newLength)
由於 Vue 不允許動態添加根級響應式屬性,所以你必須在初始化實例前聲明根級響應式屬性,哪怕只是一個空值。
異步更新隊列
可能你還沒有注意到,Vue 異步執行 DOM 更新。只要觀察到數據變化,Vue 將開啟一個隊列,並緩衝在同一事件循環中發生的所有數據改變。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩衝時去除重複數據對於避免不必要的計算和 DOM 操作上非常重要。然後,在下一個的事件循環“tick”中,Vue 刷新隊列並執行實際 (已去重的) 工作。Vue 在內部嘗試對異步隊列使用原生的 Promise.then 和 MessageChannel,如果執行環境不支持,會採用 setTimeout(fn, 0) 代替。
例如,當你設置 vm.someData = 'new value' ,該組件不會立即重新渲染。當刷新隊列時,組件會在事件循環隊列清空時的下一個“tick”更新。多數情況我們不需要關心這個過程,但是如果你想在 DOM 狀態更新後做點什麼,這就可能會有些棘手。雖然 Vue.js 通常鼓勵開發人員沿著“數據驅動”的方式思考,避免直接接觸 DOM,但是有時我們確實要這麼做。為了在數據變化之後等待 Vue 完成更新 DOM ,可以在數據變化之後立即使用 Vue.nextTick(callback) 。這樣回調函數在 DOM 更新完成後就會調用。例如:
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' // 更改數據
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
vm.$el.textContent === 'new message' // true
})
在組件內使用 vm.$nextTick() 實例方法特別方便,因為它不需要全局 Vue ,並且回調函數中的 this 將自動綁定到當前的 Vue 實例上:
Vue.component('example', {
template: '{{ message }}',
data: function () {
return {
message: '沒有更新'
}
},
methods: {
updateMessage: function () {
this.message = '更新完成'
console.log(this.$el.textContent) // => '沒有更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '更新完成'
})
}
}
})
面試題大戰:
1、vuejs與angularjs以及react的區別?
1)與AngularJS的區別
相同點:
- 都支持指令:內置指令和自定義指令。
- 都支持過濾器:內置過濾器和自定義過濾器。
- 都支持雙向數據綁定。
- 都不支持低端瀏覽器。
不同點:
- AngularJS的學習成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直觀。
- 在性能上,AngularJS依賴對數據做髒檢查,所以Watcher越多越慢。
- Vue.js使用基於依賴追蹤的觀察並且使用異步隊列更新。所有的數據都是獨立觸發的。
- 對於龐大的應用來說,這個優化差異還是比較明顯的。
2)與React的區別
相同點:
- React採用特殊的JSX語法,Vue.js在組件開發中也推崇編寫.vue特殊文件格式,對文件內容都有一些約定,兩者都需要編譯後使用。
- 中心思想相同:一切都是組件,組件實例之間可以嵌套。
- 都提供合理的鉤子函數,可以讓開發者定製化地去處理需求。
- 都不內置列數AJAX,Route等功能到核心包,而是以插件的方式加載。
- 在組件開發中都支持mixins的特性。
不同點:
- React依賴Virtual DOM,而Vue.js使用的是DOM模板。React採用的Virtual DOM會對渲染出來的結果做髒檢查。
- Vue.js在模板中提供了指令,過濾器等,可以非常方便,快捷地操作Virtual DOM。
2、請談談Vue中的MVVM模式
MVVM全稱是Model-View-ViewModel
Vue是以數據為驅動的,Vue自身將DOM和數據進行綁定,一旦創建綁定,DOM和數據將保持同步,每當數據發生變化,DOM會跟著變化。 ViewModel是Vue的核心,它是Vue的一個實例。Vue實例時作用域某個HTML元素上的這個HTML元素可以是body,也可以是某個id所指代的元素。
DOMListeners和DataBindings是實現雙向綁定的關鍵。DOMListeners監聽頁面所有View層DOM元素的變化,當發生變化,Model層的數據隨之變化;DataBindings監聽Model層的數據,當數據發生變化,View層的DOM元素隨之變化。
3、數組和對象的什麼操作vue不會響應?
由於 JavaScript 的限制, Vue 不能檢測以下變動的數組:
1 當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue
2 當你修改數組的長度時,例如: vm.items.length = newLength
受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或刪除。
Vue基礎知識
1、雙花括號
語法:
作用:
將表達式執行的結果 輸出當調用元素的innerHTML中;還可以將數據綁定到視圖
2、指令-循環指令
基本語法1:
基本語法2:
作用:
在遍歷array這個集合時,將臨時變量保存在tmp中,創建多個any標籤
3、指令-選擇指令
語法:
作用:
根據表達式執行結果的真假,來決定是否要將當前的這個元素 掛載到DOM樹
4、指令-事件綁定
語法:
作用:
給指定的元素 將handleEvent的方法綁定給指定eventName事件
5、指令-屬性綁定
基本語法:
補充,支持簡寫:
作用:
將表達式執行的結果 綁定 到當前元素的myProp屬性
動態樣式綁定
動態樣式綁定
動態樣式類綁定
動態樣式類的綁定
6、指令-雙向數據綁定
方向1:數據綁定到視圖
方向2:將視圖中(表單元素)用戶操作的結果綁定到數據
基本語法:
表單元素>
生命週期
四個階段:
create 準備工作 (數據的初始化。。。)
mount 掛載前後針對元素進行操作
update 數據發生變化,
destroy 清理工作 (關閉定時器、集合清空..)
beforeCreate/created
beforeMount/mounted
beforeUpdate/updated
beforeDestroy/destroyed
組件間通信
1、父與子通信 (props down)
1.發送
2.接受
到son組件:
Vue.component('son',{
props:['myName'],
template:`
{{myName}}
`
})
2、子與父通信 (events up)
1.綁定
methods:{
handleEvent:function(msg){}
}
2.觸發
子組件內部:
this.$emit(‘customEvent’,100);
3、ref(reference 引用/參考 外號)
幫助在父組件中 得到子組件中的數據、方法。
1.指定ref屬性
2.根據ref得到子組件實例
this.$refs.mySon
4、$parent
this.$parent得到父組件的實例
5、兄弟組件通信
1.var bus = new Vue();
2.接收方
bus.$on('eventName',function(msg){})
3.發送方
bus.$emit('eventName',123);
組件創建的方式
1、直接在template屬性中指定模板內容
1.全局組件
Vue.component
2.局部組件
{
components:{
'my-footer':{template:``}
}
}
2、.vue結尾的文件
<template>
<script>
<style>
3、單獨指定一個模板內容
Vue.component('',{
template:'#myContent'
})
面試題大戰:
1、v-model是什麼?怎麼使用? vue中標籤怎麼綁定事件?
可以實現雙向綁定,指令(v-class、v-for、v-if、v-show、v-on)。vue的model層的data屬性。綁定事件:
2、mvvm框架是什麼?它和其它框架(jquery)的區別是什麼?哪些場景適合?
一個model+view+viewModel框架,數據模型model,viewModel連接兩個
區別:vue數據驅動,通過數據來顯示視圖層而不是節點操作。
場景:數據操作比較多的場景,更加便捷
3、說出至少4種vue當中的指令和它的用法?
v-if:判斷是否隱藏;v-for:數據循環出來;v-bind:class:綁定一個屬性;v-model:實現雙向綁定
4、v-show和v-if指令的共同點和不同點?
v-show指令是通過修改元素的displayCSS屬性讓其顯示或者隱藏
v-if指令是直接銷燬和重建DOM達到讓元素顯示和隱藏的效果
5、如何讓CSS只在當前組件中起作用?
將當前組件的
閱讀更多 互聯網技能圖譜 的文章