iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
1
自我挑戰組

網頁前端框架 Vue 3 從頭開始(重新挑戰)系列 第 9

vue3 Composition API 學習手冊-9 計算屬性

  • 分享至 

  • xImage
  •  

今天來跟大家分享一個在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 vs. Function


確實將程式透過上述方式的修改,一樣能夠完成計算且看起來的效果完全一樣,而且函數還可以透過綁定元素去執行,這樣為何麼我要多學一個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>

上面的範例是透過頁面讓使用者輸入:

  • First Name:名
  • Last Name:姓
  • FullName(自動運算):自動組合名+姓(Function -> fullName)
  • Gender:性別
  • Height:身高
  • Weight:體重
  • BMI(自動運算):自動透過身高與體重運算(Computed -> bmi)
  • Suggestion(自動運算):自動透過BMI計算(Computed -> bmiMessage)

值得注意的是我們為了讓大家了解Function和Computed,FullName的計算我們透過Function來做,其他兩項我們透過Computed來完成,方便大家比對這樣製作上效能上的差異,大家可以透過下面的影片來看看實際操作上的執行狀態:

Yes

在上面的案例可以觀察出,我們總共透過表單與資料進行了六次的互動(改變First Name、Last Name、Gender、Height、Weight),從console中可以發現fullName的function也執行了六次,但兩個computed僅各執行了兩次(因為改變Height、Weight),由此可以看出來function會在每個數據更新的時候都會執行一次,這樣在效能上一定不如computed來得好。

上面的案例在說明了computed的特性“暫存”,在參考的資料變動後才會觸發重新運算,但當然此篇是希望能讓大家了解computed和function分別的利用時機,並不是一昧的要大家全部去使用computed,必須要了解兩者的特性才是。

有興趣的也可以玩玩看範例檔,記得打開console看看指令執行的狀況喔!


上一篇
vue3 Composition API 學習手冊-8 v-for為何要定義key呢?
下一篇
vue3 Composition API 學習手冊-10 計算屬性的setter
系列文
網頁前端框架 Vue 3 從頭開始(重新挑戰)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言