談談VUE種methods watch和compute的區別和聯絡

談談VUE種methods watch和compute的區別和聯絡

從作用機制和性質上看待methods,watch和computed的關係

圖片標題[原創]:《他三個是啥子關係呢?》

 

首先要說,methods,watch和computed都是以函式為基礎的,但各自卻都不同 

而從作用機制和性質上看,methods和watch/computed不太一樣,所以我接下來的介紹主要有兩個對比:

1.methods和(watch/computed)的對比

2.watch和computed的對比

作用機制上

1.watch和computed都是以Vue的依賴追蹤機制為基礎的,它們都試圖處理這樣一件事情:當某一個資料(稱它為依賴資料)發生變化的時候,所有依賴這個資料的“相關”資料“自動”發生變化,也就是自動呼叫相關的函式去實現資料的變動。

2.對methods:methods裡面是用來定義函式的,很顯然,它需要手動呼叫才能執行。而不像watch和computed那樣,“自動執行”預先定義的函式

 【總結】:methods裡面定義的函式,是需要主動呼叫的,而和watch和computed相關的函式,會自動呼叫,完成我們希望完成的作用

從性質上看

1.methods裡面定義的是函式,你顯然需要像”fuc()”這樣去呼叫它(假設函式為fuc)

2.computed是計算屬性,事實上和和data物件裡的資料屬性是同一類的(使用上),

例如:


computed:{
fullName: function () { return this.firstName   lastName }
}

你在取用的時候,用this.fullName去取用,就和取data一樣(不要當成函式呼叫!!)

3.watch:類似於監聽機制 事件機制:

例如:


watch: {
firstName: function (val) { this.fullName = val   this.lastName }
}

firstName的改變是這個特殊“事件”被觸發的條件,而firstName對應的函式就相當於監聽到事件發生後執行的方法

watch和computed的對比

說了這麼多,下面先對watch和computed

首先它們都是以Vue的依賴追蹤機制為基礎的,它們的共同點是:都是希望在依賴資料發生改變的時候,被依賴的資料根據預先定義好的函式,發生“自動”的變化

我們當然可以自己寫程式碼完成這一切,但卻很可能造成寫法混亂,程式碼冗餘的情況。Vue為我們提供了這樣一個方便的介面,統一規則

但watch和computed也有明顯不同的地方:

watch和computed各自處理的資料關係場景不同

1.watch擅長處理的場景:一個資料影響多個資料

2.computed擅長處理的場景:一個資料受多個資料影響

watch擅長處理的場景:一個資料影響多個資料

 

(具體的看上圖就ok,這裡不再贅述)

對於watch,我們先從一個場景說起

在《海賊王》裡面,主角團隊的名稱叫做:“草帽海賊團”

所以我們把船員依次稱為:

草帽海賊團索隆,草帽海賊團娜美,以此類推。。。

我們希望:當船團名稱發生變更的時候,這艘船上所有船員的名字一起變更!!

例如:

有一天,船長路飛為了加強團隊建設,弘揚海賊文化,決定“草帽海賊團”改名為“橡膠海賊團”(路飛是橡膠惡魔果實能力者)

我們程式碼如下: 


var vm = new Vue({
el: '#app',
/*
data選項中的資料:
1.haiZeiTuan_Name --> 海賊團名稱
2.船員的名稱 = 海賊團名稱(草帽海賊團)   船員名稱(例如索隆)
這些資料裡存在這種關係:
(多個)船員名稱資料 --> 依賴於 --> (1個)海賊團名稱資料
一個資料變化 ---> 多個資料全部變化
*/
data: {
haiZeiTuan_Name: '草帽海賊團',
suoLong: '草帽海賊團索隆',
naMei: '草帽海賊團娜美',
xiangJiShi: '草帽海賊團香吉士'
},
/*
在watch中,一旦haiZeiTuan_Name(海賊團名稱)發生改變
data選項中的船員名稱全部會自動改變 (suoLong,naMei,xiangJiShi)
並把它們列印出來
*/
watch: {
haiZeiTuan_Name: function (newName) {
this.suoLong = newName   '索隆'
this.naMei = newName   '娜美'
this.xiangJiShi = newName   '香吉士'
console.log(this.suoLong)
console.log(this.naMei)
console.log(this.xiangJiShi)
}
}
})
// 更改watch選項中監控的主資料
vm.haiZeiTuan_Name = '橡膠海賊團'

demo:

於是船員們的稱號字首都被統一修改了!(原本是“草帽海賊團”)

但是我們的路飛船長又突發奇想:我這麼喜歡吃肉,乾脆我們叫做“肉肉海賊團”好了吧!

我們把最下面的程式碼改為:


// 更改watch選項中監控的主資料
vm.haiZeiTuan_Name = '肉肉海賊團'

demo:

 

computed擅長處理的場景:一個資料受多個資料影響

 

我們再從一個場景說起

路飛的全名叫做:蒙奇-D-路飛,他想成為海賊王,但路飛的爺爺卡普(海軍英雄)因此感到非常惱怒,於是把“路飛”改成了叫“海軍王”,希望他能改變志向

程式碼如下:


var vm = new Vue({
el: '#app',
/*
data選項中的資料:firstName,secName,thirdName
computed監控的資料:lufei_Name
兩者關係: lufei_Name = firstName   secName   thirdName
所以等式右邊三個資料任一改變,都會直接修改 lufei_Name
*/
data: {
// 路飛的全名:蒙奇·D·路飛
firstName: '蒙奇',
secName: 'D',
thirdName: '路飛'
},
computed: {
luFei_Name: function () {
return this.firstName   this.secName   this.thirdName
}
}
})
// 將“路飛”改為“海軍王”
vm.thirdName = '海軍王'
// 列印路飛的全名
console.log(vm.luFei_Name)

demo:

 

 但是:

有一天,路飛的逗逼爺爺卡普,一不小心發現可能把族譜搞錯了,實際上,他們不是“D”之一族,而是“H”一族,也就是說,“蒙奇-D-路飛”可能要叫做“蒙奇-H-路飛”了

將最後一段程式碼改為如下:


// 將“D”改為“H”
vm.secName = 'H'
// 列印路飛的全名
console.log(vm.luFei_Name)

demo:

 

methods不處理資料邏輯關係,只提供可呼叫的函式

相比於watch/computed,methods不處理資料邏輯關係,只提供可呼叫的函式 


new Vue({
el: '#app',
template: '<div id="app"><p>{{ say() }}</p></div>',
methods: {
say: function () {
return '我要成為海賊王'
}
}
})

從功能的互補上看待methods,watch和computed的關係

  

在很多時候,computed是用來處理你使用watch和methods的時候無法處理,或者是處理起來並不太恰當的情況的

利用computed處理methods存在的重複計算情況

1.methods裡面的函式就是一群“耿直Boy”,如果有其他父函式呼叫它,它會每一次都“乖乖”地執行並返回結果,即使這些結果很可能是相同的,是不需要的

2.而computed是一個“心機Boy”,它會以Vue提供的依賴追蹤系統為基礎,只要依賴資料沒有發生變化,computed就不會再度進行計算

例子: 


new Vue({
el: '#app',
// 設定兩個button,點選分別呼叫getMethodsDate,getComputedDate方法
template: '<div id="app"><button @click="getMethodsDate">methods</button><button @click="getComputedDate">computed</button></div>',
methods: {
getMethodsDate: function () {
alert(new Date())
},
// 返回computed選項中設定的計算屬性——computedDate
getComputedDate: function () {
alert(this.computedDate)
}
},
computed: {
computedDate: function () {
return new Date()
}
}

 第一次點選methods按鈕:

 

第二次點選methods按鈕:

注意兩次點選methods返回的時間是不同的!!

 第一次點選computed按鈕:

 

第二次點選computed按鈕:

 

 注意兩次點選computed返回的時間是相同的!!

1.兩次點選methods返回的時間是不同的

2.注意兩次點選computed返回的時間是相同的

 【注意】為什麼兩次點選computed返回的時間是相同的呢?new Date()不是依賴型資料(不是放在data等物件下的例項資料),所以computed只提供了快取的值,而沒有重新計算

 只有符合:1.存在依賴型資料 2.依賴型資料發生改變這兩個條件,computed才會重新計算。 

而methods下的資料,是每次都會進行計算的 

利用computed處理watch在特定情況下程式碼冗餘的現象,簡化程式碼

 


new Vue({
el: '#app',
data: {
fullName: '彭湖灣',
firstName: '彭',
secName: '湖',
thirdName: '灣'
},
// watch中的程式碼顯然是同型別,重複的,它並不簡潔,也不優雅
watch: {
firstName: function (newValue) {
this.fullName = newValue   this.secName   this.thirdName
console.log(this.fullName)
},
secName: function (newValue) {
this.fullName = this.firstName   newValue   this.thirdName
console.log(this.fullName)
},
thirdName: function (newValue) {
this.fullName = this.firstName   this.secName   newValue
console.log(this.fullName)
}
}
})

watch中的程式碼顯然是同型別,重複的,它並不簡潔,也不優雅,所以我們可以把它變成這樣


new Vue({
el: '#app',
data: {
fullName: '彭湖灣',
firstName: '彭',
secName: '湖',
thirdName: '灣'
},
// 對watch中的程式碼進行重構,實現同樣效果
computed: function () {
this.fullName = this.firstName   this.secName   this.thirdName
console.log(this.fullName)
}
})

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援指令碼之家。

您可能感興趣的文章:

Vue.js每天必學之計算屬性computed與$watchvue.js中$watch的用法示例vue使用watch 觀察路由變化,重新獲取內容詳解vue2 $watch要注意的問題Vue.js計算屬性computed與watch(5)vue如何實現observer和watcher原始碼解析Vue.js 中的 $watch使用方法深入對Vue.js $watch方法的理解Vue.Js中的$watch()方法總結Vue.js中關於偵聽器(watch)的高階用法示例