iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

我的Vue學習筆記系列 第 3

Day03-資料加工與邏輯整合(methods v.s. computed)

網頁製作完成,在檢查的時候卻發現有錯的表格內容,而同樣的表格內容卻在多個頁面出現,要改就要重工五次,這就是我時常碰到的問題。不僅浪費時間難維護,也有可能手誤其中一頁沒有改好,這時有了methods和computed可以一次改也降低改錯的機會。

Methods方法

在不認識methods之前會在{{...}}裡面寫{{price*quantity}},知道有methods用法後會將重複的部分取出來包在函式中,之後要使用只需要寫{{subTotal()}}就可以叫出一樣的數值。

<p>金額共{{subTotal()}}元</p>
<!-- 中間略... -->
<p>金額共{{subTotal()}}元</p>
<!-- 中間略... -->
<p>金額共{{subTotal()}}元</p>
const vm = Vue.createApp({
    data() {
        return {
            price: '100',
            quantity: '10'
        }
    },
    methods: {
        subTotal: function () {
            return this.price * this.quantity
        }
    }
}).mount('#app')

補充: this.pricethis.quantity中的this指的是跟他包一起的data內數值

若是在methods使用箭頭函式會怎麼樣呢?

methods: {
    subTotal: () => {
        return this.price * this.quantity
    }
}

此時的this會變成window,所以畫面就會出現

一般函式在建立時是在 window 下,所以在 window 下使用箭頭函式自然會指向 window,要確實將箭頭函式宣告在物件內部,這樣 this 才會指向該物件。— 擷取自 卡斯伯's Blog

Computed計算屬性

寫法跟methods差不多

//省
methods: {
    subTotal: () => {
        return this.price * this.quantity
    }
},
computed: {
    subTotal: function () {
        return this.price * this.quantity
    }
}
//省

差異處在於HTML模板中少了()

<p>金額共{{subTotal}}元</p>

這是不是代表著他們兩個是可以互相通用的呢?

接著來做個測試....

const vm = Vue.createApp({
    data() {
        return {
            price: '100',
            quantity: '10'
        }
    },
    methods: {
        subTotalMethods: function () {
            console.log('methods')
            return this.price * this.quantity
        }
    },
    computed: {
        computedComputed: function () {
            console.log('subTotal')
            return this.price * this.quantity
        }
    }
}).mount('#app');
<p>金額共{{subTotalMethods()}}元</p>
<p>金額共{{computedComputed}}元</p>
methods
subTotal

結果答案都是100*10,也就是1000,且console中都各執行一次。從這個角度來看似乎兩者並沒有差異。

<p>金額共{{subTotalMethods()}}元</p>
<p>金額共{{subTotalMethods()}}元</p>
<p>金額共{{subTotalMethods()}}元</p>

<p>金額共{{computedComputed}}元</p>
<p>金額共{{computedComputed}}元</p>
<p>金額共{{computedComputed}}元</p>

得到的結果

methods
methods
methods
subTotal

subTotalMethods()出現幾次就會執行幾次。而computedComputed只會執行一次,會有這樣的結果是因為

  • computed 是在監控資料更動後,重新運算結果呈現於畫面上一般來說不會修改資料,只會回傳用於畫面呈現的資料
  • methods 就是互動的函式,需要觸發才會運作會用來修改資料內容效能

使用時機

舉書本上的貨幣範例:

methods

<div id="app">
	<p>日幣 = 0.278 台幣</p>
	<div>台幣 <input type="text" v-model="twd" v-on:input="twd2jpy"></div>
	<div>日幣 <input type="text" v-model="jpy" v-on:input="jpy2twd"></div>
<div>

//v-model是將input資料與data內的資料做綁定
//v-on是監聽作用,觸發事件後會執行方法
const vm = Vue.createApp({
    data() {
        return {
            twd: 0.278,
            jpy: 1
        }
    },
    methods: {
        twd2jpy: function () {
            this.jpy = Number.parseFloat(Number(this.twd) / 0.278).toFixed(3)
        },
        jpy2twd: function () {
            this.twd = Number.parseFloat(Number(this.jpy) * 0.278).toFixed(3)
        }
    },
}).mount('#app');

個幣當輸入事件v-on:input被觸發時,就會去執行各自綁定的function,每執行一次methods就會跑一次。

computed

<div id="app">
  <p>日幣 = 0.278 台幣,且 1 美金 = 28.540 台幣:</p>
  <div>台幣 <input type="text" v-model="twd"></div>
  <div>日幣 <input type="text" v-model="jpy"></div>
  <div>美金 <input type="text" v-model="usd"></div>
</div>
const vm = Vue.createApp({
    data() {
        return {
            twd: 1000,
        }
    },
    computed: {
        jpy: {
            get() {
                return Number.parseFloat(Number(this.twd) / 0.278).toFixed(3)
            },
            set(val) {
                this.twd = Number.parseFloat(Number(val) * 0.278).toFixed(3)
            }
        },
        usd: {
            get() {
                return Number.parseFloat(Number(this.twd) / 28.540).toFixed(3)
            },
            set(val) {
                this.twd = Number.parseFloat(Number(val) * 28.540).toFixed(3)
            }
        }
    }
}).mount('#app');

在HTML模板上面看到了v-model="jpy",但data裡面卻只有twd的資料卻沒有jpy,也就是說computed可以產生data資料,jyp的資料透過computed對twd加工計算,在jpy更新的時候透過set()改寫twd的內容。

methods 和 computed 的差異:

若有效能上的考量,建議採用 computed 的版本。最主要是 computed 有緩存資料的能力,因此會將「屬性計算後的結果暫存」。當資料修改時,computed 也會隨之修改,但這是針對於 data 有變化時。反之 methods 每次執行就會每次計算一次,在效能上考量就比較差。

如果資料量大,computed 自然會比較慢,只要資料變動就會觸發,無形之中執行次數也會增加勒,因此在大量資料時,會建議透過 methods 減少不必要的運算。

參考資料

卡斯伯's Blog — 鐵人賽:箭頭函式 (Arrow functions)
https://wcc723.github.io/javascript/2017/12/21/javascript-es6-arrow-function/
Vue 筆記 - Computed 的 get() 與 set()
https://hsuchihting.github.io/vue-js/20200917/2086781732/


上一篇
Day02-Vue.js的實體
下一篇
Day04-Vue指令
系列文
我的Vue學習筆記30

1 則留言

0
liawyudye
iT邦新手 5 級 ‧ 2021-09-18 14:41:37

沒有注意到箭頭函示的this指向
筆記起來~
/images/emoticon/emoticon13.gif

我要留言

立即登入留言