Vue-101-Day 6

|

在 template 置放太多運算式或邏輯判斷,可能會造成 template 臃腫 或是 程式碼難以維護,看程式碼的時候可能需要花時間理解。 遇到複雜的邏輯處理時,應該使用 computed property

以下為例

這是一個反轉文字的函式,假使反轉文字會重複使用,樣板內的程式就會很亂、很雜,就會更難處理。

<div id="app-2">
    <p>
       {{ foo.split('').reverse().join('') }} 
    </p>
</div>

這個時候就需要 computed property 來幫助,將程式更改為如下寫法

<div id="app-2">
  <p>Original message: {{ foo }}</p>
  <!-- Original message: bar -->
  <p>Reverse message: {{ reverseMessage }}</p>
  <!-- Reverse message: rab -->
</div>
const obj = {
  foo: 'bar'
}

var app2 = new Vue({
  el: '#app-2',
  data: obj,
  computed: {
    reverseMessage: function() {
      return this.foo
        .split('')
        .reverse()
        .join('')
    }
  }
})

上面範例的寫法也可以透過 methods 來達成

<div id="app-2">
  <p>Original message: {{ foo }}</p>
  <!-- Original message: bar -->
  <p>Reverse message: {{ reverseMessage() }}</p>
  <!-- Reverse message: rab -->
</div>
const obj = {
  foo: 'bar'
}

var app2 = new Vue({
  el: '#app-2',
  data: obj,
  methods: {
    reverseMessage: function() {
      return this.foo
        .split('')
        .reverse()
        .join('')
    }
  }
})

Computed Caching vs Methods

使用 computed 及 methods 都可以達到所要的結果。

差別在於 computed 根據相依資料改變才做計算; methods 不管有無相依都會改變

依下所示範例來看,在一開始的時候是沒有差異的

<div id="app-2">
  <p>message: </p>
  <p>now (computed): </p>
  <p>now (methods): {{ getNow() }}</p>
</div>
const obj = {
  foo: 'bar'
}

var app2 = new Vue({
  el: '#app-2',
  data: obj,
  computed: {
    now: function() {
      return Date.now()
    }
  },
  methods: {
    getNow: function() {
      return Date.now()
    }
  }
})

輸出結果

message: bar

now (computed): 1558156303492

now (methods): 1558156303492

所以在五秒後執行以下程式碼,輸出結果也會跟著改變

setTimeout(() => {
  app2.foo = 1234
}, 5000)

輸出結果

message: 1234

now (computed): 1558159214487

now (methods): 1558159220862
  1. 需呈現最新資料就給 methods

  2. 再意效能就給 computed

Computed vs Watched Property

Vue 提供 watch 屬性來監聽資料。

下述範例利用 名(firstName) + 姓(lastName) 取得全名(fullName)

使用 watch 需要同時監聽 名(firstName) 以及 姓(lastName) 屬性,多宣告一個 fullName 變數(儲存目前的資料值為何),只要任一資料異動即更新 fullName

若使用 computed ,fullName 即為 firstName 及 lastName,只有要有任一變動,就會自動取得最新資料

<div id="demo">
  <p>fullName(watch) :{{ fullName }}</p>
  <p>fullName(computed) :{{ getFullName }}</p>
</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'David',
    lastName: 'Wu',
    fullName: 'David Wu'
  },
  computed: {
    getFullName: function() {
      return this.firstName + ' ' + this.lastName
    }
  },
  watch: {
    firstName: function(val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function(val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

輸出結果

fullName(watch) :David Wu

fullName(computed) :David Wu

Computed Setter

computed 屬性預設只有 get,也可以設置 Setter

下示範例可以在 fullName 裡面覆寫 setter,將 fullName 改為 Chia Peng

var vm2 = new Vue({
  el: '#full-name',
  data: {
    firstName: 'David',
    lastName: 'Wu'
  },
  computed: {
    fullName: {
      get: function () {
        return this.firstName + ' ' + this.lastName
      },
      set: function (newValue) {
        var names = newValue.split(' ')
        this.firstName = names[0]
        this.lastName = names[names.length - 1]
      }
    }
  }
})
setTimeout(() => {
  vm2.fullName = 'Chia Peng'
  console.log(vm2.firstName) // Chia
  console.log(vm2.lastName) // Peng
}, 5000)

參考資料:

Comments