Vue 初心者筆記 #13 計算 (Computed) 與監聽 (Watch)

在 Vue.js 中,在 Methods、Computed、Watch 裡面都可以寫函式,這三種屬性有什麼差異呢?

方法 (Methods)

主動觸發,可以重複觸發

Methods 裡的 Function 通常會藉由一個「按鈕」之類的 Trigger 來啟用功能,把資料重新繪製到畫面上。

計算 (Computed)

資料出現變化,需要改變畫面

Computed 可以省略這個按鈕,當資料出現變化時透過 Function 改變畫面。

範例一:過濾資料

使用 Computed 來過濾資料

1
2
3
4
5
6
<input type="text" v-model="filterText">
<ul>
<li v-for="(item, key) in filterArray" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var app = new Vue({
el: '#app',
data: {
arrayData: [
{
name: '小明',
age: 16,
},
{
name: '漂亮阿姨',
age: 24,
},
],
},
filterText: '',
computed: {
filterArray: function () {
let vm = this;
return vm.arrayData.filter(function (item) {
return item.name.match(vm.filterText);
});
},
},
});

用這種方式就不需要用一個按鈕去觸發 Method 來計算畫面的訊息,速度比較快。
但如果資料量大,效能上可能會有影響。

範例一補充:this

第一個 this 是指向 app 這個變數。
第二個 this 是全域的 window

因為直接呼叫 filter() 這個全域的方法,所以 this 會改為指向 window
也就是因為 this 會改變,所以一開始才要將 this 放入變數 vm 內。

範例一補充:return

第一個 return 是回傳給予 filterArray 用的。
第二個是 filter() 陣列方法帶入確認過濾內容的。

第二個 return 後面的條件如果成立 (item.name 等於 vm.filterText),
就會回傳 arrayData 裡面的「單個物件」給第一個 return 讓它回傳給 filterArray

範例二:呈現時間格式

使用 Computed 來呈現時間格式

1
2
3
<!-- 把 newDate 放到畫面上
這是一個 Timestamp -->
<p>{{ formatTime }}</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var app = new Vue({
el: '#app',
data: {
newDate: 0, // 要繪製到畫面上的時間格式
},
computed: {
formatTime: function () {
console.log(this.newDate);
var dates = new Date(this.newDate * 1000);
var year = dates.getFullYear();
var month = dates.getMonth() + 1;
var date = dates.getDate();
var hours = dates.getHours();
var minutes = dates.getMinutes();
var seconds = dates.getSeconds();
// 拼湊時間格式
// ${} 是 ES6 的寫法 (Template String)
return `${year}/${month}/${date} ${hours}:${minutes}:${seconds}`;
},
},

// mounted
mounted: function () {
this.newDate = Math.floor(Date.now() / 1000);
},
});

監聽 (Watch)

監控特定資料變化

Watch 通常用於「監控」特定的變數,當變數產生變化時,可以執行特定的事件 (Function)。

例如:按下按鈕 (trigger) 讓畫面產生變化,並觸發 Watch 裡面的事件。

範例:旋轉盒子

使用 trigger 來觸發旋轉 box,並在三秒後改變回來

1
2
<div class="box" :class="{'rotate': trigger }"></div>
<button class="btn" @click="trigger = true">旋轉</button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var app = new Vue({
el: '#app',
data: {
// 被監控的變數 trigger
trigger: false,
}
watch: {
// 產生變化時,執行以下函式
trigger: function(){
let vm = this;
// ES6 箭頭函式
setTimeout(() => {
vm.trigger = false;
}, 3000);
},
},
});

按下按鈕後,按鈕的 @click="trigger = true" 成功觸發 box 的程式碼 :class="{'rotate': trigger }",讓 box 旋轉 45 度。

但是因為變數 trigger 產生變化,所以觸發了 Watch 裡面的事件。
三秒後 Watch 就會將 trigger 改回 false,box 就會轉回來。

總結

  • Methods:需要「主動觸發」,且可以多次重複觸發。
  • Computed:當「資料出現變化」時需要改變畫面的 Function 放這裡。
  • Watch:「監控」特定資料變化的 Function 放這裡。

其中,ComputedWatch 很像,因為都會隨著資料做變化,但是這兩種最大的差異在於「效能」。
而「效能」的主要差異就在於會不會調整資料:

  • Computed 是用來呈現在畫面上的 Function。
  • Watch 則會變動其它資料。

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。