Vue.js เริ่มต้น ตอน6 (Computed Properties and Watchers)

27 May 2018,
Share: 

ก่อนหน้านี้เราได้เรียนรู้กันไปแล้วว่าใน Template จะจัดการเกี่ยวกับการแสดงผล ซึ่งในบางครั้งเราจําเป็นต้องนํา Logic บางอย่างใส่เข้าไปใน Template ด้วย ซึ่งเราก็จะใส่ไปแบบนี้

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

แบบนี้ก็ไม่ผิดครับ แต่จะยากลําบากเมื่อเรา Maintain ระบบ Vue.js ก็แก้ปัญหาโดยแยกมันออกมาซะ โดยเรียกมันว่า Computed แบบนี้ครับ

<template>
  <div id="example">
    <p>Original message: "{{ message }}"</p>
    <p>Computed reversed message: "{{ reversedMessage }}"</p> <br />
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data: function () {
    return {
      message: 'Hello'
    }
  },
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
}
</script>

จะได้แบบนี้ครับ

Image

ข้อมูลของ reversedMessage จะขึ้นอยู่กับ message เมื่อ message เปลี่ยน จะรัน reversedMessage ใหม่

Computed vs Methods

โดยปกติแล้วเราสามารถใช้ Method ได้เหมือนกัน แบบนี้

<template>
  <div id="example">
    <p>Reversed message: "{{ reverseMessage() }}"</p>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data: function () {
    return {
      message: 'Hello'
    }
  },
  methods: {
    reverseMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
}
</script>

ซึ่งจะได้ผลลัพธ์เหมือนกัน แต่มีมีสิ่งที่แตกต่างกันคือ Method จะเรียก Function ทุกครั้งที่ Component re-render ใหม่ ซึ่งต่างจาก Computed จะไม่เรียก Function เมื่อ ข้อมูลไม่เปลี่ยน ตัวอย่าง

<template>
  <div id="example">
    <p>Date: "{{ now }}"</p>
    <p>Date from Method: "{{ reverseMessageInMethod() }}"</p>
    <p>Date from Computed: "{{ reversedMessageInComputed }}"</p> <br />
    <button type="button" v-on:click="changeDate()">Click to update date</button>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data: function () {
    return {
      now: Date.now()
    }
  },
  methods: {
    changeDate: function () {
      this.now = Date.now()
    },
    reverseMessageInMethod: function () {
      return Date.now()
    }
  },
  computed: {
    // a computed getter
    reversedMessageInComputed: function () {
      // `this` points to the vm instance
      return Date.now()
    }
  }
}
</script>

ทุกครั้งที่กดปุ่ม Date from Method จะเปลี่ยนแปลง แต่ Date from Computed จะไม่เปลี่ยนแปลง เพราะว่า เมื่อ now เปลี่ยน ทําให้ Component ทําการ Render ใหม่ ส่งผลให้ Method reverseMessageInMethod() ถูกเรียกให้ทํางานอีกครั้ง แต่ Computed จะไม่ทํางานเนื่องจาก ข้อมูลใน function ไม่มีการเปลี่ยนแปลง ก็จะใช้ค่าเดิมก่อนหน้านี้

Computed vs Watched Property

Vue มีทางเลือกหลายทางที่จะเฝ้าดูการเปลี่ยนแปลงของข้อมูล และ Watched Property ก็เป็นอีกทางเลือกนึง การทํางานของ Watched Property  คือ เฝ้าดูว่าข้อมูลในตัวแปลที่เรากําหนดมีการเปลี่ยนแปลงหรือไม่ ถ้ามีการเปลี่ยนแปลงก็จะรันคําสั่งที่เราเขียนไว้ จะมีประโยชน์ในกรณีที่ เมื่อเราต้องการให้ ข้อมูล A เปลี่ยน แล้ว ข้อมูล B จะต้องเปลี่ยนด้วย ตัวอย่าง

<template>
  <div id="example">
    <div id="demo">{{ fullName }}</div>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data: function () {
    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>

ซึ่งจะให้ผลลัพธ์เหมือนกันกับ Compute ตามตัวอย่างนี้

<template>
  <div id="example">
    <div id="demo">{{ fullName }}</div>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  data: function () {
    return {
      firstName: 'Foo',
      lastName: 'Bar'
    }
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
}
</script>

ก็ลองเลือกใช้งานกันดูนะครับ นอกจากนี้เรายังสามารถนําค่าก่อนที่จะเปลี่ยนแปลงมาใช้งานใน Funtion ได้อีกด้วย

watch: {
  firstName: function (newVar, oldVar) {
    ...
  }
}

Computed Setter

โดย Default Computed จะเป็น Read only หรือ Getter ได้อย่างเดียว แต่เราสามารถ จะเพิ่ม Setter ได้ด้วย ตามตัวอย่างนี้ครับ

// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

เมื่อเรารันคําสั่ง this.fullName = ‘John Doe’ Setter ก็จะทํางานครับ จบ!!! โปรดคิดตามตอนต่อไป…

Suggestion blogs

เหรียญ 1 บาท เนื่องในวันอาหารโลก

เหรียญ 1 บาท เนื่องในวันอาหารโลก พ.ศ.2525 องค์การอาหารและเกษตรแห่งสหประชาชาติขอความร่วมมือให้กรมธนารักษ์จัดทำเหรียญกษาปณ์ที่ระลึกเนื่องในวันอาหารโลก องค์การอาหารและเกษตรแห่งสหประชาชาติเป็นองค์การระหว่างประเทศที่ดำเนินการเกี่ยวกับการเพิ่มผลผลิตในการเกษตรให้มากยิ่งขึ้น เพื่อมิให้ประชากรของโลกขาดแคลนอาหาร และเนื่องด้วยวันที่ 16 ตุลาคม พ.ศ. 2524 เป็นวันฉลองการก่อตั้งองค์การอาหารและการเกษตรแห่งสหประชาชาติ ครบปีที่ 36 องค์การ ฯ จึงถือเอาวันที่

เปลี่ยน port xrdp raspberry pi

สวัสดีครับ ในบทความที่แล้วผมเขียนเรื่องการ ติดตั้ง xrdp ไปแล้ว ในบทความนี้ผมจะมาสอนวิธีเปลี่ยน port ของ xrdp

pointer c/c++

pointer เป็นชนิดข้อมูลประเภทหนึ่งที่สร้างจากชนิดข้อมูลแบบพื้นฐานทั่วไป โดยชนิดข้อมูลแบบ pointer จะแตกต่างกับชนิดข้อมูลพื้นฐานตรงที่ชนิดข้อมูลแบบพื้นฐานจะเก็บและดึงข้อมูลจากตัวแปรโดยตรง แต่ชนิดข้อมูลแบบ pointer จะเก็บค่าที่อยู่(Address) ของตัวแปรอื่น และใช้ค่าที่อยู่นี้อ้างอิงไปยังข้อมูลที่เก็บอยู่ในตัวแปรนั้นอีกที เพื่อทําการเก็บและดึงข้อมูลจากตัวแปรนั้นอีกที


Copyright © 2019 - 2026 thiti.dev |  v1.60.2 |  Privacy policy | 

Build with ❤️ and Astro.

Github profile   Linkedin profile   Instagram   X profile   Nostr   Youtube channel   Telegram   Email contact   วงแหวนเว็บ