iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Modern Web

30 天我與 Vue 的那些二三事系列 第 7

Day 7 - 計算屬性和監聽器

計算屬性(Computed Property)

當我們今天想針對某一變數做運算或是處理時,可以透過模板內的表達式,但是在模板中放入太多的邏輯會讓模板過重且難以維護。誠如上一節所提到的觀念,我們應該把數據處理與頁面細節分開。

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

這時候我們便可以透過Vue的計算屬性來定義我們想要的邏輯。

<template>
  <div id="app">
    <span>Message: {{ msg }}</span
    ><br />
    <span>Message: {{ reversedMessage }} </span>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      msg: "Hello World!",
    };
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.msg.split("").reverse().join("");
    },
  },
};
</script>

結果如下,這裡我們聲明了一個計算屬性,並在屬性中對msg這個變數進行逆轉字串的處理。
https://ithelp.ithome.com.tw/upload/images/20210922/201289251Ll6NANWeU.png

不過,這時候你可能會發現,那我用一般的method不就可以達到一樣的效果了嗎?

的確是這樣的,我們可以使用method完成同樣的事情:

<template>
  <div id="app">
    <span>Message: {{ msg }}</span
    ><br />
    <span>Message: {{ reversedMessage() }} </span>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      msg: "Hello World!",
    };
  },
  methods: {
    reversedMessage() {
      return this.msg.split("").reverse().join("");
    },
  }
};
</script>

那計算屬性的優勢在哪裡呢? 讓我們仔細分曉。

計算快取 (Computed cache)

計算屬性的優勢在於,若資料沒有更新,則該屬性的 DOM 會顯示上一次計算好的內容,稱為 computed cache。

儘管可以使用method達到一樣的效果,但意義上來說是明確不同的。

使用method可以用以下敘述解釋,當每次 rerender 時 reverseMessage 會重新計算結果,因此如果 msg 在過程中有變更,則 reverseMesage 的結果也會跟著改變。

但若是計算屬性的話,則可以解釋為,因為我們更新了 message,這個操作會重新計算,並更新 computed cache。

使用 computed cache 的時機是,當有個需要消耗較多運算資源的資料(例如 AJAX)需要被顯示在很多地方時,若用 method 則每個地方該方法都會被重新運算,會造成相當大的資源消耗,此時有 computed cache 可以大幅增進效能。

監聽屬性(Watched Property)

Vue 提供了一種相當方便的方式來觀察Vue instance的資料,稱作監聽屬性。適用於當我們有一些資料需要隨著其它資料變動而更新時。

當 firstName 或 lastName 被更新時,watch 會去執行對應的兩個函式,進而更新 fullName。

<template>
  <div id="app">
    {{ fullName }}
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      firstName: "Foo",
      lastName: "Bar",
      fullName: "Foo Bar",
    };
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + " " + this.lastName;
    },
    lastName: function (val) {
      this.fullName = this.firstName + " " + val;
    },
  },
};
</script>

不過,由於watch屬性需要一直去監聽資料變化,相較於計算屬性會比較耗效能,所以最好評估是否真的有需要一直去監聽特定資料,不然的話,盡量使用計算屬性來代替。


Hi, I am Grant.

個人部落格 - https://grantliblog.wordpress.com/
個人網站 - https://grantli-website.netlify.app/#/mainpage
我的寫作專題 - https://vocus.cc/user/5af2e9b5fd89780001822db4#


上一篇
Day 6 - Vue事件處理
下一篇
Day 8 - 初探Vue Component
系列文
30 天我與 Vue 的那些二三事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言