前言

這篇主要介紹 computedwatch 這兩個 Options API。


Computed 計算屬性

在模板中表達式非常的便利,但如果在模板中放入太複雜的邏輯,它會讓模板過度複雜。例如,我們想反轉一個字串:

<div id="app">
  <p>{{ string.split('').reverse().join('') }}</p>
</div>
const app = Vue.createApp({
  data() {
    return {
      string: 'Hello World'
    }
  }
})

在上面程式碼可以看到,我們在模板裡放入這種複雜的表達式,畫面會變得非常雜亂,為解決此問題,我們可以把這些表達式寫在 computed 屬性裡:

<div id="app">
  <p>{{ reversedString }}</p> <!-- dlroW olleH -->
</div>
const app = Vue.createApp({
  data() {
    return {
      string: 'Hello World'
    }
  },
  computed: {
    reversedString() {
      return this.split('').reverse().join('')
    }
  }
}).mount('#app')

computed 會將參考的資料結果暫存起來,當參考資料改變時,computed 就會重新計算。所以如果我們嘗試改變 string 的值,你會看到 reversedString 跟著變更。


computed VS methods

這邊你可能會發現依靠 methods 也能達到同樣的效果,比如說:

<div id="app">{{ reversedString() }}</div>
const app = Vue.createApp({
  data() {
    return {
      string: 'Hello World'
    }
  },
  computed: {
    reversedString() {
      return this.split('').reverse().join('')
    }
  }
}).mount('#app')

不同的是 computed 是依據參考資料的改變來去做計算,而 methods 是不管有沒有相依資料,只要觸發了就會改變。還有一點就是 computed 可以運用在 v-for 上:

<div id="app">
  <p v-for="(item, index) in showed">{{ item.name }}</p>
</div>
const app = Vue.createApp({
  data() {
    return {
      person: [
        { name: 'Tom', isShow: false },
        { name: 'Lucy', isShow: true },
        { name: 'Aible', isShow: true },
      ]
    }
  },
  computed: {
    showed() {
      // 顯示 isShow 等於 true 的人
      return this.person.filter(item => item.isShow === true)
    }
  },
}).mount('#app')

以這種方式我們能在 v-for 計算大量的資料,並且當 person 有變動時,computed 也會更新。


getter 和 setter

computed 屬性預設只有 getter,但你也可以在需要使用時設定 setter,需要注意的是,如果你需要傳入 gettersetter,則要在 computed 使用 object 而不是 function,例如:

<div id="app">
  <p>{{ fullName }}</p>
</div>
const app = Vue.createApp({
  data() {
    return {
      firstName: 'Curise',
      lastName: 'Tom'
    }
  },
  computed: {
    // 使用物件形式
    fullName: {
      get() {
        return this.firstName + ' ' + this.lastName
      },
      set(newValue) {
        // do what you want to do...
      }
    }
  }
}).mount('#app')

懶人包

  1. 使用 function 型式時,此時會作為 getter,且沒有 setter
  2. 使用 Object 型式時,使用 get()set() 會作為 gettersetter

watch 監聽器

watch 在 Vue 中是用來檢查某個屬性值是否有出現變動,如果有則做出某些操作。例如我們想在一個名字欄位變動時就 console 出它已變動的訊息:

<div id="app">
  <h4>Name</h4>
  <input type="text" v-model="name">
</div>
const app = Vue.createApp({
  data() {
    return {
      name: 'tom',
    }
  },
  watch: {
    name(newVal, oldval) {
      console.log(`Name is Changed to ${newVal}, old val is ${oldval}`);
    },
  }
}).mount('#app')

watch
這裡我們監聽 name 的屬性值,當 name 變動時,就用 console 印出訊息。

Tips
watch 監聽的對象可傳入兩個參數,第一個為改變後的值,第二個為改變前的值。


參考

Vue 官網
Danny 的學習紀錄