那些關於Vue 的小細節- Computed 中getter 和setter 觸發的 ...

文章推薦指數: 80 %
投票人數:10人

另外,在getter 中,要記得搭配使用return 來把值返回出來。

基本的寫法如下:. 預設只有getter 的computed. new Vue({ ... //Skiptocontent 2017年5月9日 文章撰寫時使用[email protected] 在Vue中computed是經常會使用到的屬性,因為在Vue中透過computed會cache住沒有改變的資料,因此正確且適當的使用computed將可以減少資料重新運算的次數,讓網頁的效能提升。

但是在使用的過程中,有時候會發現computed怎麼樣就是不被觸發,這當中有些細節是我們可以進一步瞭解的。

computed的基本觀念 在Vue中,computed的屬性可以被視為像是data一樣,可以讀取和設值,因此在computed中可以分成getter(讀取)和setter(設值),在沒有寫setter的情況下,computed預設只有getter,也就是只能讀取,不能改變設值。

雖然說computed內的屬性可以被視為像是data一樣,但在使用上,一般還是會讓computed類似唯讀的狀態,也就是去處理`data`資料,然後把它吐出來使用。

另外,在getter中,要記得搭配使用return來把值返回出來。

基本的寫法如下: 預設只有getter的computed newVue({ computed:{ computedData:function(){ return//... } } }) 有setter和getter的computed newVue({ computed:{ computedData:{ get:function(){ return//... }, set:function(){ //... } } } }) 程式範例連結 下面的部分包含許多程式說明,你可以開啟這份Codepen,然後開啟console視窗搭配閱讀。

[Vue]關於VueComputed的那些小細節(LearnComputedinDeep)@CodePen 一般情況下getter觸發的時間點 在一般的情況下,我們可以這樣使用computed(只有getter)來更新資料,你可以直接打開Codepen的第一部分,或者程式碼如下: 一般情況computedgetter被觸發的時間點

{{fullName}}

//js:computed-basic newVue({ el:'#computed-basic', data:{ firstName:'PJ', lastName:'Chen' }, computed:{ fullName(){ console.log('computedgetter') returnthis.firstName+''+this.lastName } }, updated(){ console.log('updated') } }) 在這個情況下,我們只要輸入input的內容,改變了this.firstName或this.lastName時,就會觸發getter,也就是說,computed的getter會觀察被寫在裡面的資料,一般來說,當被觀察的資料改變時,這個getter就會被觸發。

聽起來非常合理,但是我們用console.log()看一下,分別看computedgetter和updated的時間點,你會發現,當我們在input輸入資料,會觸發computed,同時也會觸發這個vm的updated。

getter的例外情況:資料變更但getter不會被觸發 剛剛我們提到當getter裡面被觀察的資料有變更時,就會觸發computed,但這個說其實並不完全正確,有些時候畫面更新了,資料變更了,但其實不會觸發computed裡面的getter。

如果我們把template中的fullName拿掉,換成firstName和lastName時(程式碼如下):

firstName:{{firstName}},lastName:{{lastName}}

也就是當我們的template中沒有馬上用到這個computed的資料時(這裡的話就是指fullName),那麼Vue不知道你要用到fullName,因此即使我們變更了this.firstName和this.lastName,依然不會觸發getter。

我們可以在console中看到,firstName和lastName資料變更的情況下,只會一直得到updated而已,computed中的getter並不會被觸發。

一般情況下setter觸發的時間點 接著,讓我們來看一下在一般的情況下,computed的setter什麼時候會被觸發: 一般情況computedsetter被觸發的時間點

firstName:{{firstName}}
lastName:{{lastName}}

//js //computed-setter-basic newVue({ el:'#computed-setter-basic', data:{ firstName:'PJ', lastName:'Chen' }, computed:{ fullName:{ get(){ console.log('computedgetter') returnthis.firstName+''+this.lastName }, set(value){ console.log('computedsetter') this.firstName=value.split('')[0] this.lastName=value.split('')[1] } } }, updated(){ console.log('updated') } }) 從template中,我們可以看到,我們的input是直接綁v-model="fullName",因此他會直接去修改fullName的值,而當前fullName是computed中的一個屬性,我們說過computed中的屬性就和data類似可以取值(getter)和設值(setter),這時候因為我們要對fullName設值,自然就會對應到fullName裡面的setter(如果沒有設定setter是無法對fullName設值的)。

簡單來說,當computed的屬性要被設值時,就會觸發setter,從console中我們也可以看到,當我在input中輸入內容時,fullName會改變,fullName改變的情況會觸發setter,接著,因為我的setter中所做的事會變更到getter中所觀察的資料,這時候才又觸發getter執行,最後重新updated畫面。

也就是從setter->getter->updated這樣的過程,如下圖所示: 觸發setter不必然會觸發getter 在上面的例子中,我們會先觸發setter,接著觸發getter,最後updated畫面。

但是其實getter會被觸發是因為我們在setter中變更到了被getter所觀察的資料。

也就是說,如果我們的setter在執行時,並不會觸發getter所觀察的資料的話,那麼getter就不會被觸發。

例如,當我把上面程式碼的setter中對於資料的變更註解掉時: set(value){ console.log('computedsetter') //this.firstName=value.split('')[0] //this.lastName=value.split('')[1] } 那麼即時我們在input中輸入內容,都只會觸發setter而不會觸發getter。

換句話說,setter和getter是獨立觸發的,兩個被觸發的時間點是不同的。

總結 在這篇文章中,我們進一步瞭解了Vuecomputed中的getter和setter,有幾個重點可以整理一下 getter和setter彼次觸發的時間點是獨立的。

getter在大部分的時候是當內部觀察的資料有改變時會被觸發;setter則是當被觀察的物件本身有改變時會被觸發。

getter在畫面中沒有使用到被觀察的物件時,不會被觸發。

這篇的內容主要是根據自身的經驗和理解,如果有任何錯誤,都歡迎不吝告知,以避免錯誤的知識傳遞,謝謝! 5/10更新,感謝網友@AyshSu(聖涵/亞所) 修正觀念錯誤 Share: 較新的文章 較舊的文章 首頁 0 意見: 張貼留言



請為這篇文章評分?