iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
自我挑戰組

每天來點 Vue.js 吧系列 第 7 篇

Vue computed property `getter` 與 `setter` 的那些事

  • 分享至 

  • xImage
  •  

Computed Property ✐

在 computed 中設置的 property 稱為 Computed Property 計算屬性,Computed Property 於 Option 中透過 computed 設置,能夠幫助我們將複雜的邏輯自模板中提出,保持模板的簡潔。而能夠將模板中的計算邏輯移入 computed 中,多虧於 getter 的運作,由於 Vue (V2)實際上透過 Object.defineProperty 設置 Computed Property 的 getter 以及 setter,一旦調用 Computed Property,getter 便能作為 包裝器 處理我們要取得的結果,例如計算該年歲數、姓氏與名稱的結合,都是十分適用的情境。

源碼中的 computed 研究:

上面提及的 Object.defineProperty 可以自 Vue 2.x 源碼中窺見一二,我們可以看到 Vue 在底層 defineComputed 函式中使用 Object.defineProperty(target, key, sharedPropertyDefinition) 定義 setter、getter 的過程:

export function defineComputed (
  target: any,
  key: string,
  userDef: Object | Function
) {
  const shouldCache = !isServerRendering()
  if (typeof userDef === 'function') {
    sharedPropertyDefinition.get = shouldCache
      ? createComputedGetter(key)
      : userDef
    sharedPropertyDefinition.set = noop
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? shouldCache && userDef.cache !== false
        ? createComputedGetter(key)
        : userDef.get
      : noop
    sharedPropertyDefinition.set = userDef.set
      ? userDef.set
      : noop
  }
  if (process.env.NODE_ENV !== 'production' &&
      sharedPropertyDefinition.set === noop) {
    sharedPropertyDefinition.set = function () {
      warn(
        `Computed property "${key}" was assigned to but it has no setter.`,
        this
      )
    }
  }
  // here
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

(以上為部分源碼節錄)

自 computed 設置 get、set

一般來說 Vue 中 Computed Property 可以單純的傳入 function,該 function 會被作為 getter,此時的 Computed Property 沒有 setter,無法設置值。若是要對 Computed Property 設置 getter、setter 兩者,則需要傳入 Object,透過在傳入的物件中設置 getter、setter 函式達成設置。

用法上來說,可以濃縮成以下兩點:

  • Computed Property 設置 function,該 function 會作為 getter,此時無 setter。
  • Computed Property 設置 { get: fun, set: fun },兩者會作為 getter、setter。

Computed 的簡單應用

Computed 適用在需要對原 data 做一些小加工的地方,舉例來說將姓氏與名稱兩筆資料結合、計算年齡,就十分合適,除此之外由於模板中只支援 expression,使用 computed 便能使用 statement 等更為複雜的計算情境,也是很大的優點,以下列出實際應用。

將 姓氏 與 名稱 結合:

const vm = new Vue({
  el: "#app",
  data: {
    lastName: "金",
    firstName: "小雅"
  },
  computed: {
    name: function () {
      return this.lastName + ' ' + this.firstName;
    }
  }
});

除此之外,若是希望透過該 computed property 設置 firstName 與 lastName,則可以設置以下的 setter 實現:

const vm = new Vue({
  el: "#app",
  data: {
    lastName: "金",
    firstName: "小雅"
  },
  computed: {
    name: {
      get: function () {
        return this.lastName + " " + this.firstName;
      },
      set: function (value) {
        const name = value.split(" ");
        this.lastName = name[0];
        this.firstName = name[1];
      }
    }
  }
});

最後,由於 computed 中的 getter、setter 函式 this 值皆會綁定為 Vue instance,如同前幾章節所講述的原因(this),請不要使用 arrow function。以上為此次內容,感謝看到這裡的你,我們明天見。


待補:

若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦

▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification

▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM


參考資料:

  1. Vuejs.org 2.x
  2. 属性的 getter 和 setter
  3. Vue2.0 源码阅读:响应式原理 | zhouweicsu
  4. Alex 宅幹嘛 從事件到資料|以 Vue.js 為例 談談前端開發思維轉變 - YouTube
  5. day 05 getter & setter: 屬性描述器
  6. 计算属性 VS 侦听属性 | Vue.js 技术揭秘
  7. 等待學習:Usage with Vue | XState Docs
  8. 等待學習:Using State Machines in Vue.js with XState | frontstuff

上一篇
Vue template 模板語法
下一篇
Vue computed 與 method 的差異比較
系列文
每天來點 Vue.js 吧 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
mangoSu
iT邦新手 5 級 ‧ 2020-09-27 18:36:46

每天來點 vue 也順便來點 BTS/images/emoticon/emoticon34.gif

/images/emoticon/emoticon37.gif

我要留言

立即登入留言