? ? ? ?emmmmm,,之前因為開項目來不及仔細讀一遍,只能是用到什么找什么,然而深感對vue了解的無力(?д?;)。。還有一個周開新項目,恩,認真看一哈!( ̄▽ ̄)
【本文并沒有講解全部API,因為太多了。。總結了部分我覺得重要的點加以分析】
傳送門:Vue.js中文API
Vue參考MVVM模式,使用vm (ViewModel 的簡稱)來表示Vue實例
? ? ? ?vue是一個虛擬DOM的,以數(shù)據(jù)驅(qū)動為核心的前端框架。數(shù)據(jù)驅(qū)動也可以稱為響應式系統(tǒng),當屬性的值發(fā)生變化時,視圖都會“及時響應”,并更新相應的新值。
實例生命周期鉤子函數(shù)
? ? ? ?每個 Vue 實例在被創(chuàng)建之前,都要經(jīng)過一系列的初始化過程,例如,Vue 實例需要設置數(shù)據(jù)觀察(set up data observation)、編譯模板(compile the template)、在 DOM 掛載實例(mount the instance to the DOM),以及在數(shù)據(jù)變化時更新 DOM(update the DOM when data change)。在這個過程中,Vue 實例還會調(diào)用執(zhí)行一些生命周期鉤子函數(shù),這樣用戶能夠在特定階段添加自己的代碼。

? ? ? ?(圖可能不是很清晰,小伙伴們可以參考原圖)
- 對于數(shù)據(jù)的操作,比如props、data、computed的初始化都是在beforeCreate與created之間完成的,所以不了解的時候很可能會出現(xiàn)在別的鉤子操作數(shù)據(jù)而產(chǎn)生奇奇怪怪的問題。
- 有一點要注意, 一般情況下vue組件總是會走完全部的生命周期的,即使你在created或者其他早期的生命周期鉤子中使用了路由跳轉或者location.herf重定向。
- 一些因生命周期問題而導致無法使頁面刷新的問題有如下解決方案:
①this.nextTick({ })具體使用方法請移步傳送門
②vuex
③setTimeout(code,millisec) 【可以強制推遲頁面加載xx毫秒,強烈不推薦,暫緩之計,具體病因還是要具體解決】 - 生命周期鉤子是一個很強大的功能,可以很好地處理掛載以及異步加載相關的事件,在特定階段執(zhí)行特定的代碼,比如某幾張圖的出現(xiàn)順序、比如axios請求數(shù)據(jù)來異步刷新等。
- 注意,任何生命周期鉤子 中 this 上下文都會指向調(diào)用它的 Vue 實例。
關于生命周期具體理解推薦一篇文章來自segmentfault
3. 關于computed和watcher,留個flag,匯總一下再寫
4. 修飾符(modifier)是以 . 表示的特殊后綴,表明應當以某種特殊方式綁定指令。
? ? ? ?關于修飾符,請移步我的一篇搬運文章? Vue修飾符詳解
5. 渲染
? ? ? ?1. 根據(jù)條件進行渲染:v-if與v-show
-
v-if與v-show可以對內(nèi)容進行靈活的選擇性加載,是使用比較多的指令。
? ? ? ?其二者的區(qū)別是,v-if是“真實”的條件渲染,因為它會確保條件塊(conditional block)在切換的過程中,完整地銷毀(destroy)和重新創(chuàng)建(re-create)條件塊內(nèi)的事件監(jiān)聽器和子組件。且v-if是惰性的(lazy),如果在初始渲染時條件為 false,它不會執(zhí)行任何操作。直到在條件第一次變?yōu)?true 時,才開始渲染條件塊。
? ? ? ?相比之下,v-show 要簡單得多 - 不管初始條件如何,元素始終渲染,并且只是基于 CSS 的切換。
? ? ? ?通常來說,v-if 在切換時有更高的性能開銷,而 v-show 在初始渲染時有更高的性能開銷。因此,如果需要頻繁切換,推薦使用 v-show,如果條件在運行時改變的可能性較少,推薦使用 v-if。
v-if的渲染控制
? ? ? ?2. 列表渲染:v-for
- 在 v-for 代碼塊中,我們可以完全地訪問父級作用域下的屬性。v-for 還支持可選的第二個參數(shù),作為當前項的索引:
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
結果:
- 也可以使用 v-for 來遍歷對象的屬性,接著提供第二個參數(shù),作為對象的鍵名(key),然后第三個參數(shù)作為索引(index):
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
結果:
注意,在遍歷一個對象時,是按照 Object.keys() 得出 key 的枚舉順序來遍歷,無法保證在所有 JavaScript 引擎實現(xiàn)中完全一致。
- 關于key,下列是API的原文
<div v-for="item in items" :key="item.id">
<!-- content -->
</div>
推薦在使用 v-for 時,盡可能提供一個 key,除非迭代的 DOM 內(nèi)容足夠簡單,
或者你是故意依賴于默認行為來獲得性能提升。
由于這是 Vue 識別節(jié)點的通用機制,因此 key 并不是僅限于與 v-for 關聯(lián),
我們將在之后的指南中看到,key 還可以其他場景使用。
因為沒有用到過所以不是很理解,給個flag后續(xù)了解。
-
帶有v-if的v-for
當它們都處于同一節(jié)點時,v-for 的優(yōu)先級高于 v-if。這意味著,v-if 將分別在循環(huán)中的每次迭代上運行。當你只想將某些項渲染為節(jié)點時,這會非常有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
-
關于v-once
用法:<span v-once></span>
在API中給出的建議是性能優(yōu)化,事實也確實如此,不過需要注意的是,用v-once指令修飾的html內(nèi)容在加載的時候會且只會加載一次
? ? ? ?劃重點?。。?!
? ? ? ?3. 數(shù)組變化檢測(Array Change Detection)
? ? ? ?Vue 將觀察數(shù)組(observed array)的變化數(shù)組方法(mutation method)包裹起來,以便在調(diào)用這些方法時,也能夠觸發(fā)視圖更新。這些包裹的方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
由于 JavaScript 的限制,Vue 無法檢測到以下數(shù)組變動:
- 當你使用索引直接設置一項時,例如
vm.items[indexOfItem] = newValue- 當你修改數(shù)組長度時,例如
vm.items.length = newLength
? ? ? ?所以,使用Vue.set(example1.items, indexOfItem, newValue)來解決第一個問題,
使用example1.items.splice(indexOfItem, 1, newValue)來解決第一和第二個問題。
這兩種方法可以通過響應式系統(tǒng)觸發(fā)狀態(tài)更新。
? ? ? ?4. 對象變化檢測(Array Change Detection)
受現(xiàn)代 Javascript 的限制, Vue 無法檢測到對象屬性的添加或刪除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 是響應的 vm.b = 2 // `vm.b` 不是響應的? ? ? ?Vue 不允許在已經(jīng)創(chuàng)建的實例上,動態(tài)地添加新的根級響應式屬性(root-level reactive property)。然而,可以使用 Vue.set(object, key, value) 方法,將響應式屬性添加到嵌套的對象上。例如:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } }})? ? ? ?可以向嵌套的 userProfile 對象,添加一個新的 age 屬性:
? ? ? ?Vue.set(vm.userProfile, 'age', 27)
? ? ? ?還可以使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名:
? ? ? ?vm.$set(this.userProfile, 'age', 27)
? ? ? ?這是剛接觸Vue的時候踩到過的一個大坑,現(xiàn)在想起來還頭皮發(fā)麻
∑(?Д?ノ)ノ
6. DOM 模板解析
當時用DOM模板時,會受到一些來源于HTML的限制,比如,這種寫法是報錯的:
<table>
<!--my-row是自定義模板-->
<my-row>...</my-row>
</table>
解決方案:
<table>
<tr is="my-row"></tr>
</table>
is屬性請自行百度。
敲黑板
在使用以下字符串模板之一的場景中,這些限制將不再適用:
- <script type="text/x-template">
- JavaScript 內(nèi)聯(lián)模板字符串
- .vue 組件
所以,用.vue吧,畢竟用的就是vue框架233333_(:з」∠)_
7. 組件復用
組件(component)是 Vue 最強大的功能之一。組件可以幫助你擴展基本的 HTML 元素,以封裝可重用代碼。
在編寫組件時,記住是否要復用組件有好處。一次性組件跟其它組件緊密耦合沒關系,但是可復用組件應當定義一個清晰的公開接口。
Vue 組件的 API 來自三部分 - props, events 和 slots :
- Props 允許外部環(huán)境傳遞數(shù)據(jù)給組件
- Events 允許組件對外部環(huán)境產(chǎn)生副作用(side effects)
- Slots 允許外部環(huán)境將額外的內(nèi)容組合在組件中。
8. 組件的組合與通信
組件,意味著組合在一起使用的元件,多數(shù)場景是父子關系:組件 A 可以在自己的模板中使用組件 B。這就必然的需要彼此相互通信:父組件可能會向下傳遞數(shù)組給子組件,然后子組件也可能會將自身發(fā)生的變化通知到父組件。然而,重要的是,為了盡可能將父子組件解耦,需要有一個定義清晰的接口。定義清晰的通信方式,可以確保組件可以相對隔離地組織代碼,以及合乎邏輯易于推斷,從而使它們更加易于維護,并且可能更加易于復用。
vue的大方面的功能核心就是組件,正是組件的組合嵌套復用構成了快速且多樣的vue項目生態(tài)圈,而組件通信又是組件中比較重要的知識點。
-
父向子組件:
- 在子組件中添加props(既可以傳遞數(shù)據(jù)也可以傳遞方法)
常用形式<child :msg = "parentMsg"/>
含有路由出口的使用形式<router-view :propsdata="data"/> - this.$broadcast 調(diào)用子組件方法(子組件在events中寫被調(diào)用方法)
- 父組件通過this.$ref獲得子組件的引用
【$refs 只在組件渲染完成后才填充,并且它是非響應式的。它僅僅作為一個直接訪問子組件的應急方案 - 應當避免在模板或計算屬性中使用 $refs。】 - 使用this.$children()獲得子組件的Vue實例
- 在子組件中添加props(既可以傳遞數(shù)據(jù)也可以傳遞方法)
-
子向父組件:
- this.$emit (父組件在methods中寫被調(diào)用方法,并通過@event綁定到子組件) ,子組件中通過這種方法傳遞數(shù)給父組件同時激活父組件的被調(diào)用方法。
- this.$dispath (父組件在events中寫被調(diào)用方法)
- 在子組件中添加插槽slot,父組件可以向子組件中插入模板 <template/> ,通過slot-scope獲得子組件返回的值
- 使用this.$parent獲得父組件Vue實例 (this.$root獲得根組件的Vue實例)
一點補充:在某些場景中,我們可能需要對一個 prop 進行「雙向綁定」 - 事實上,這個功能在 Vue 1.x 中已經(jīng)由
.sync修飾符實現(xiàn)。但是在2.0中移除,在2.3.0+中以語法糖的形式再次加入。雖然用的不多,如果想了解請移步API。
- 通過bus.js或者自身的vue實例來進行不同組件之間的數(shù)據(jù)傳遞
- 通過new一個Vue對象作為通信的橋梁(bus.$emit() => bus.$on())
- 自身的vue實例(this.$emit() => this.$on())
- Flux以及Vuex(全局單例模式)同時也可用于解決不同組件之間的通信問題(解決了繁雜事件訂閱和廣播)
- 路由傳參
這里要注意,第一種方式是無法傳參的,要傳參必須通過第二種方式,即以name的形式而不能以路徑的形式。所以在路由中的定義如下第三張圖。
不帶參帶參路由表中的定義
關于slot,與props相似,簡單來說就是props把數(shù)據(jù)扔到子組件中,slot把html扔到子組件中。關于slot留個flag后續(xù)寫個專欄具體補充。。。
請注意,props是單向數(shù)據(jù)流,按照自上而下單向流動方式構成
9. 動態(tài)組件
- 簡單來說,與v-bind動態(tài)選擇css一個樣子,根據(jù)父組件給的變量決定顯示哪個組件,或者都不顯示。
- 使用方式:
<component v-bind:is="組件名"></component> - 有一點需要注意,像v-if一樣,動態(tài)加載組件是需要重渲染的,所以如果想避免重新渲染可以添加keep-alive屬性來保持已渲染的組件不被移除。
<component v-bind:is="組件名" keep-alive></component> - activate延遲加載
activate是和data等屬性平級的一個屬性,形式是一個函數(shù),函數(shù)里默認有一個參數(shù),而這個參數(shù)是一個函數(shù)。
如下實例:
data(){
return{
//...
}
},
activate (done) { //執(zhí)行這個參數(shù)時,才會切換組件
var self = this;
//
axios.get("/test", function (data) {
self.hello = data;
done(); //ajax執(zhí)行成功,切換組件
})
}
注意:
【1】只有在第一次渲染組件時,才會執(zhí)行activate,且該函數(shù)只會執(zhí)行一次(在第一次組件出現(xiàn)的時候延遲組件出現(xiàn))
【2】沒有keep-alive時,每次切換組件出現(xiàn)都是重新渲染(因為之前隱藏時執(zhí)行了destroy過程),因此會執(zhí)行activate方法。
10. 組件雜項
以下全部有待補充,慣例,flaggggggggggggg
- 異步組件/代碼分離
應用做大了以后可以進行性能優(yōu)化,后續(xù)詳細補充 - 命名規(guī)范
- 組件之間的循環(huán)引用
- 組件庫
- 其他
11. 過渡&動畫
概述
過渡和動畫可以對頁面內(nèi)容以及用戶體驗做一些良好的提升,避免生硬的切換效果帶來的挫頓感。個人看法:如果不考慮模塊化發(fā)布或者工程量不是很大,在系統(tǒng)功能完善之后進行過度動畫的添加可以對頁面逼格進行大幅提升~
從頁面中添加(顯示)、移除(隱藏)或者更新一些成員的時候,Vue提供了多種的過渡動畫來避免生硬的元素轉變。包括以下工具:
- 在 CSS 過渡和動畫中自動處理 class
- 可以配合使用第三方 CSS 動畫庫,如 Animate.css
- 在過渡鉤子函數(shù)中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 動畫庫,如 Velocity.js
單元素/組件的過渡
Vue提供了transition外層包裹容器組件(wrapper component),可以給下列情形中的任何元素和組件添加進入/離開(enter/leave)過渡:
- 條件渲染(使用 v-if)
- 條件展示(使用 v-show)
- 動態(tài)組件
- 組件根節(jié)點
一個demo:
<template>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</template>
<script>
new Vue({
el: '#demo',
data: {
show: true
}
})
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active 在低于版本 2.1.8 中 */ {
opacity: 0;
}
</style>



