今天來跟大家分享一個在Vue裡面非常方便實用的屬性:計算屬性,它可以在Vue中的數據更改後,自動進行運算取得一個新的結果,例如:
<div id="app">
<p>
<input type="number" v-model="state.number1"> +
<input type="number" v-model="state.number2"> = {{ result }}
</p>
</div>
<script>
const { reactive, computed } = Vue;
const app = {
setup(){
const state = reactive({
number1: 0,
number2: 0,
})
const result = computed(() => {
if(isNaN(state.number1) || isNaN(state.number2)){
return "Error!! Please enter the number."
}else{
return parseFloat(state.number1) + parseFloat(state.number2);
}
})
return { state, result };
}
}
const myVue = Vue.createApp(app).mount("#app");
</script>
上面這個範例中,只要變更了Vue中的number1與number2後,computed就會自動加總兩個輸入文字的值,並顯示在後方,若使用者輸入的不是數字則會顯示錯誤訊息。
PS:使用computed之前記得先將它他從vue當中取出來唷~(Javascript程式碼第一行)
雖然這個方法大家應該能理解,但聰明的你應該知道我們可以透過自訂函數來完成這個功能。
<div id="app">
<p>
<input type="text" v-model="state.number1"> +
<input type="text" v-model="state.number2"> = {{ result() }}
</p>
</div>
<script>
const { reactive } = Vue;
const app = {
setup(){
const state = reactive({
number1: 0,
number2: 0,
})
function result(){
if(isNaN(state.number1) || isNaN(state.number2)){
return "Error!! Please enter the number."
}else{
return parseFloat(state.number1) + parseFloat(state.number2);
}
}
return { state, result };
}
}
const myVue = Vue.createApp(app).mount("#app");
</script>
那究竟何時要使用Computed呢?請看下面的說明:
確實將程式透過上述方式的修改,一樣能夠完成計算且看起來的效果完全一樣,而且函數還可以透過綁定元素去執行,這樣為何麼我要多學一個computed呢?重點應該是他的“暫存”機制,但上面這個案例太過於簡單,所以沒辦法看出這樣的效果,我們透過下面的案例進行說明:
<div id="app">
<p>First Name: <input type="text" v-model="state.firstName"></p>
<p>Last Name: <input type="text" v-model="state.lastName"></p>
<p>Full Name:{{ fullName() }}</p>
<p>Gender:
<select v-model="state.gender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</p>
<p>Height:<input type="text" v-model="state.height">CM</p>
<p>Weight:<input type="text" v-model="state.weight">KG</p>
<p>BMI:{{ bmi }}</p>
<p>Suggestion:{{ bmiMessage }}</p>
</div>
<script>
const { reactive, computed } = Vue;
const app = {
setup(){
const state = reactive({
firstName: "Stanley",
lastName: "Ma",
gender: "Male",
height: 180,
weight: 80,
})
const bmi = computed(() => {
console.log("Run BMI Computed");
return state.weight / (Math.pow((state.height / 100), 2));
})
const bmiMessage = computed(() => {
console.log("Run BMI Message Computed");
if (bmi.value > 35) {
return "重度肥胖";
} else if (bmi.value >= 30 && bmi.value < 35) {
return "中度肥胖";
} else if (bmi.value >= 27 && bmi.value < 30) {
return "輕度肥胖";
} else if (bmi.value >= 24 && bmi.value < 27) {
return "過重";
} else if (bmi.value >= 18.5 && bmi.value < 24) {
return "正常範圍";
} else {
return "體重過輕";
}
})
function fullName() {
console.log("Run fullName Function");
return state.firstName + " " + state.lastName;
}
return { state, bmi, bmiMessage, fullName };
}
}
const myVue = Vue.createApp(app).mount("#app");
</script>
上面的範例是透過頁面讓使用者輸入:
值得注意的是我們為了讓大家了解Function和Computed,FullName的計算我們透過Function來做,其他兩項我們透過Computed來完成,方便大家比對這樣製作上效能上的差異,大家可以透過下面的影片來看看實際操作上的執行狀態:
在上面的案例可以觀察出,我們總共透過表單與資料進行了六次的互動(改變First Name、Last Name、Gender、Height、Weight),從console中可以發現fullName的function也執行了六次,但兩個computed僅各執行了兩次(因為改變Height、Weight),由此可以看出來function會在每個數據更新的時候都會執行一次,這樣在效能上一定不如computed來得好。
上面的案例在說明了computed的特性“暫存”,在參考的資料變動後才會觸發重新運算,但當然此篇是希望能讓大家了解computed和function分別的利用時機,並不是一昧的要大家全部去使用computed,必須要了解兩者的特性才是。
有興趣的也可以玩玩看範例檔,記得打開console看看指令執行的狀況喔!