05.19 Vue2.0復仇者聯盟之無限面試題

Vue2.0復仇者聯盟之無限面試題

大家知道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復仇者聯盟之無限面試題

檢測變化的注意事項

受現代 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 更新完成後就會調用。例如:

{{message}}

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只在當前組件中起作用?

將當前組件的


分享到:


相關文章: