iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 7
0
自我挑戰組

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

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

Computed Property ✐

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

源碼中的 computed 研究:

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

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 設置 gettersetter 兩者,則需要傳入 Object,透過在傳入的物件中設置 gettersetter 函式達成設置。

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

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

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 設置 firstNamelastName,則可以設置以下的 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 中的 gettersetter 函式 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

1 則留言

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

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

/images/emoticon/emoticon37.gif

我要留言

立即登入留言