vue筆記-----深入響應式原理
簡單且直觀,不過理解它的工作原理以避免一些常見的問題也是很重要的。
如何追蹤變化
把一個普通的JavaScript物件傳給Vue例項的data選項,Vue將遍歷此物件的搜遊屬性
,並使用Object.defineProperty把這些屬性全部轉為getter/setter。Object.
defineProperty是僅ES5支援,且無法shim的特性,這也就是為什麼Vue不支援IE8以
及耕地版本瀏覽器的原因。
使用者看不到getter/setter,但是在內部它們讓Vue追蹤依賴,在屬性被訪問和修改時
通知變化。這裡需要注意的問題是瀏覽器控制檯在列印資料物件時getter/setter的
格式化並不同,所以你可能餘姚安裝vue-devtools來獲取更加友好的檢查介面。
每個元件例項都有相應的watcher例項物件,它會在元件渲染的過程中把屬性記錄為
依賴,之後當以來想的setter被呼叫時,會通知watcher重新計算.
變化檢測問題
受現代JAvaScript的限制(以及飛起Object.observe),Vue不能檢測到物件屬性的
新增或刪除。由於vue會在初始化例項時對屬性執行getter/setter轉化過程,所以屬
性必須在data物件上存在才能讓Vue轉換它,這樣才能讓它是響應的
var vm = new Vue({
data:{
a:1
}
})
//vm.a是響應式的
vm.b = 2
//vm.b是非響應式的
Vue不允許在已經建立的例項上動態新增新的根級響應式屬性。然而他可以使用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})
宣告響應式屬性
由於Vue不允許動態新增根級響應式屬性,所以你必須在初始化例項前宣告根級響應式
屬性,哪怕只是一個空值:
var vm = new Vue({
data:{
//宣告message為一個空值字串
message:''
}
template:'<div>{{message}}</div>'
})
//之後設定message
vm.message='Hello'
如果你在data選項中未宣告message,Vue將警告你渲染函式在試圖訪問的屬性不存在。
#過渡效果
vue在插入、更新或者移除DOM時,提供多種不同方式的應用過渡效果。
在css過度和動畫中自動應用class
可以配合使用第三方css動畫庫,如Animate.css
在過度鉤子函式中使用JavaScript直接操作DOM
可以配合使用第三方JavaScript動畫庫,如Velocity.js
#單元素/元件的過度
Vue提供了transition的封裝元件,在下列情形中。可以給任何元素和元件新增entering/
leaving過度
*條件渲染(使用v-if)
*條件展示(使用v-show)
*動態元件
*元件根節點
這是一個典型的例子
<div id="demo">
<button v-on:click="show=!show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
new Vue({
el:'#demo',
data:{
show:true
}
})
.fade-enter-active,.fade-leave-active{
transition:opacity .5s
}
.fade-enter,.fade-leave-active{
opacity:0
}
當插入或刪除包含在transition元件中的元素時,Vue將會做以下處理:
1.自動嗅探目標元素是否應用了css過度或者動畫,如果是,在恰當的時機新增/刪除
css雷鳴。
2.如果過度元件提供了JavaSWcript鉤子函式,這些鉤子函式將在恰當的時機被呼叫。
3.如果沒有找到JavaScript鉤子並且也沒有檢測到css過度/動畫,Dom操作(插入/刪除)
在下一幀中立即執行(注意:這個幀與Vue,和Vue的nextTick概念不同)
#過度的-css類名
會有4個(css)類名在enter/leave的過度中切換
1.v-enter:定義進入過度的開始狀態。在元素被插入時生效,在下一幀移除。
2.v-enter-active:定義進入過渡的結束狀態。在元素被插入時生效,在transition
/animation完成後移除。
3.v-leave:定義離開過度的開始狀態。在離開過度被觸發時生效,在下一幀移除。
4.v-leave-active:定義離開過度的結束狀態。在離開過度被觸發時生效,在
transition/animation完成後移除。
對於這些在enter/leave過度中切換的類名,v-是這些類名的字首。使用
<transition name="my-transition">可以充值字首。比如v-enter替換為
my-transition-enter。
v-enter-active和v-leave-active可以控制進入/離開過度的不同階段。
#css過度
常用的過度否是使用css過度。
#css動畫
css動畫用法同css過度,區別是在動畫中v-enter類名在節點插入DOM後不會立即刪
除,而是在animationend事件ain觸發時刪除。
#自定義過度名
我們可以通過一下特性來自定義過度類名:
*enter-class
*enter-active-class
*leave-class
*leave-active-class
他們的優先順序高於普通的類名,這對於vue的過度系統和其他第三方css動畫哭,如
Animate.css結合使用十分有用。
#同時使用Transitions和Animations
Vue為了知道過度的完成,必須設定響應的事件監聽器。他可以是transitionend
或者animationend,這取決於給元素應用的css規則。如果你是用其中任何一種,
Vue能自動識別型別並設定監聽。
但是在一些場景中,你餘姚給同一個元素同時舍子兩種過度效果,比如animation
很快的唄觸發並完成了,而transition效果還沒結束。在這種情況中,你就需要
使用type特性並設定animation或者transition來明確你需要vue監聽的型別。
#JavaScript鉤子
可以在屬性中聲名JavaScript鉤子
這些鉤子函式可以結合Css transition/animations使用,也可以單獨是使用。
當只用JavaScript過度時候,在enter和leave總,回掉函式done是必須的。否則,
他們會被同步呼叫,過度會立即完成
推薦對於僅使用JavaScript過度的元素新增v-bind:css="false",Vue會跳過css
的檢測。這也可以避免過渡過程中css的影響。
初始渲染的過度
可以通過apear特性設定節點的初始渲染的過度