Vue核心知識:computed、methods和watch的區別
阿新 • • 發佈:2022-03-26
Vue核心知識:computed、methods和watch的區別
作用機制上
- methods,watch 和 computed 都是以函式為基礎的,但各自卻都不同
- watch 和 computed 都是以 Vue 的依賴追蹤機制為基礎的,當某一個數據發生變化的時候,所有依賴這個資料的“相關”資料“自動”發生變化,也就是自動呼叫相關的函式去實現資料的變動
- methods 裡面是用來定義函式的,它需要手動呼叫才能執行。而不像 watch 和 computed 那樣,“自動執行”預先定義的函式,相比於 watch / compute;methods 不處理資料邏輯關係,只提供可呼叫的函式,類似儲存函式的一個庫
性質上
- methods 裡面定義的是函式,仍然需要去呼叫它。
- computed 是計算屬性,在使用上和 data 物件裡的資料屬性是同一類的,底層藉助了Objcet.defineproperty方法提供的getter和Isetter.
- watch:類似於監聽機制+事件機制,當被監視的屬性變化時,回撥函式自動呼叫,進行相關操作
載入順序
1. computed
是在 HTML DOM 載入後馬上執行的,如賦值; 計算後的屬性將直接賦值到vue例項中
2. methods
頁面渲染完成後,必須要有一定的觸發條件才能執行,如點選事件,
3. watch
它用於觀察 Vue 例項上的資料變動。
4. 預設載入的時候
先 computed 再 watch,不執行 methods;
5. 觸發某一事件後
先 computed 再 methods 再到 watch,computed 計算屬性是基於它們的依賴進行快取的
區別
計算屬性computed
-
定義:要用的屬性不存在,要通過已有屬性計算得來。
-
原理:底層藉助了Objcet.defineproperty方法提供的getter和Isetter.
-
get函式什麼時候執行?
- 初次讀取時會執行一次。
- 當依賴的資料發生改變時會被再次呼叫。
-
優勢:與methods實現相比,內部有快取機制(複用),效率更高,除錯方便。
-
備註:
- 計算屬性最終會出現在vm上,直接讀取使用即可。
- 如果計算屬性要被修改,那必須寫set函式去響應修改,且set中要引起計算時依賴的資料發生改變
-
一個計算屬性裡面可以完成各種複雜的邏輯,最終返回一個結果;計算屬性可以依賴多個vue例項的資料,只要其中一個任何一個數據發生變化,計算屬性就會重新執行,檢視也會更新。除此之外,計算屬性還可以依賴其他計算屬性和其他例項的資料
應用場景:(一個數據受多個數據影響)字串拼接,購物車商品結算
new Vue({
el: '#root',
template: `
<div>
<span>Name: {{name}}</span>
</div>
`,
data: {
firstName: '張',
lastName: '三'
},
computed: {
name () {
return `${this.firstName} ${this.lastName}`
}
}
})
監聽屬性watch
監視屬性watch:
- 當被監視的屬性變化時,回撥函式自動呼叫,進行相關操作
- 監視的屬性必須存在,才能進行監視!
- watch中的函式有兩個引數,前者是newVal,後者是oldVal。
- watch中的函式是不需要呼叫的。
- 特殊情況下,watch無法監聽到陣列的變化,特殊情況就是說更改陣列中的資料時,陣列已經更改,但是檢視沒有更新。更改陣列必須要用splice()或者$set。this.arr.splice(0,1,100)-----修改arr中第0項開始的1個數據為100,this.$set(this.arr,0,100)-----修改arr第0項值為100。
- watch只會監聽資料的值是否發生改變,而不會去監聽資料的地址是否發生改變。也就是說,watch想要監聽引用型別資料的變化,需要進行深度監聽。"obj.name"(){}------如果obj的屬性太多,這種方法的效率很低,obj:{handler(newVal){},deep:true}------用handler+deep的方式進行深度監聽。
應用場景:(一個數據影響多個數據)搜尋框、表單輸入、非同步更新、動畫
new Vue({
template: `
<div>
<p>FullName: {{fullName}}</p>
<p>FirsName: <input type="text" v-model="firstName"/></p>
</div>
`,
data: {
firstName: '張',
lastName: '三',
fullName: ' '
},
watch: {
firstName (newName, oldName) {
this.fullName = newName + ' ' + this.lastName
}
}
})