Vue Computed Properties、Methods、Watch Properties
Vue:2.5
如果我們有一個需求是要反轉字串,直接針對特定字串做的話,會長這樣:
<div id="app">
{{ message.split('').reverse().join('') }}
</div>
假設這個功能是需要大量使用的話,勢必得封裝成一個 Mehtod
以供使用。
而在 Vue 中就有許多不同的做法可以解決相同的問題。
Computed Properties
Computed
是 Vue 提供的 計算屬性
,可以將一些邏輯運算的程式定義在此,變成一個動態的屬性。因此,在Computed
第一次計算過後,會將結果 cache 起來,再根據相依的 data
是否有改變而決定要不要重新計算。
Notice:
Computed
是屬性不是 method,因此使用時並不需要在句尾加()
。
範例
<div id="app">
{{ reversedMessage }}
</div>
const vm = new Vue({
el: '#app',
data: {
message: 'Hello Johnson'
},
computed: {
reversedMessage: function () {
console.log('run');
return this.message.split('').reverse().join('');
}
}
});
// 根據上面範例,呼叫多次 reversedMessage ,只會執行到一次 console.log(run),剩的都是直接輸出 Computed cahce 的資料。
vm.reversedMessage;
vm.reversedMessage;
vm.reversedMessage;
Computed
也可以自行定義 getter
和 setter
method,讓使用上更彈性。
範例
const vm = new Vue({
el: '#app',
data: {
lastName: 'Lu',
firstName: 'Johnson'
},
computed: {
fullName: {
get: function () {
return this.firstName + ' ' + this.lastName;
},
set: function (value) {
let names = value.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
}
}
}
});
// 如果沒有特別設定,預設就只會有 getter
console.log(vm.fullName);
// 當值改變時,會呼叫 setter method
vm.fullName = 'Jacky Wu';
console.log(vm.firstName);
Notice:
Computed
的使用情境就是用來實現SSOT(Single Source of Truth)
原則的。最簡單的例子就是
單位換算
,以幣值來說,你的來源只要有新台幣
,接著就可以透過Computed
動態使用多種幣值。
Methods
Methods
就是封裝一般 method 的地方,跟 Computed
唯一的差別,就是每次執行不管相依的 data
有沒有改變,都是重新做計算。
範例
const vm = new Vue({
el: '#app',
data: {
message: 'Today is '
},
methods: {
methodGetTime: function () {
return this.message + ' ' + Date.now();
},
},
computed: {
computedGetTime: function () {
return this.message + ' ' + Date.now();
}
}
});
// Computed 因為 vm.message 未改變,因此值都會相同
// Methods 會每次改變
console.log('Computed: ' + vm.computedGetTime);
console.log('Methods: ' + vm.methodGetTime());
console.log('Computed: ' + vm.computedGetTime);
console.log('Methods: ' + vm.methodGetTime());
vm.message = 'Tomorrow is ';
// vm.message 改變後,Computed 跟著重新計算
console.log('Computed: ' + vm.computedGetTime);
console.log('Methods: ' + vm.methodGetTime());
Watch Property
Watch
是用來監測你的 data
改變後,需要做些什麼事。有些情境使用 Watch
跟 Computed
都可以達到效果,端看自己對於需求的定義是什麼。
範例
const vm = new Vue({
el: '#app',
data: {
lastName: 'Lu',
firstName: 'Johnson',
fullName: 'Johnson Lu'
},
watch: {
// Key 的名稱需要與 data 名稱相同
// 只要設定的值有改變,就會執行
firstName: function (value) {
this.fullName = value + ' ' + this.lastName;
},
lastName: function (value) {
this.fullName = this.firstName + ' ' + value;
}
}
});
也可以透過 callback handler 搭配 immediate
、 deep
等屬性做更彈性的使用。
範例
const vm = new Vue({
el: '#app',
data: {
lastName: 'Lu',
firstName: 'Johnson',
fullName: 'Johnson Lu',
people: [
{id: 1, name: 'Johnson Lu'},
{id: 2, name: 'Joyce Lu'}
]
},
watch: {
firstName: {
handler: function (value, oldValue) {
this.fullName = value + ' ' + this.lastName;
},
// immediate 為 true 時,在綁定後會先觸發一次 handler
immediate: true
},
people: {
handler: function (value, oldValue) {
console.log(value[0].name);
},
// Watch 預設只會監測最上面一層,如果需要多層就必須設定 deep 屬性
deep: true
}
}
});