[Vue.js] ทำ component ให้รองรับ v-model ด้วยตัวเอง

 บทความนี้ผมจะถือว่าผู้อ่านมีความรู้เรื่อง Vue.js มาแล้วในระดับหนึ่ง เนื่องจากไม่ใช่บทความสอนการเขียน Vue.js แต่เป็นส่วนเสริมเรื่องการทำ component ขึ้นมาเองแล้วรองรับการใช้งาน v-model (ถ้ายังไม่รู้ว่า
v-model คืออะไร แนะนำให้ศึกษาเพิ่มเติมมาก่อน)



ทำให้รองรับ v-model ยังไง?

v-model มันคือการส่งข้อมูลไปกลับระหว่าง parent component และ child component ซึ่งถูกเรียกว่า two-way binding คือค่าของตัวแปรจะถูกส่งไปกลับระหว่าง 2 component นี้

ค่าตั้งต้นของการทำ v-model คือ component จะรับค่าผ่าน props ที่ชื่อว่า value และส่งค่ากลับไปด้วย event ที่ชื่อ input

ขอยกตัวอย่างโค้ดง่าย ๆ เป็น EmailInput.vue ตามนี้ละกันครับ

<template>
  <input type="email" @input="handleInput" />
</template>

<script>
export default {
  props: ['value'],
  data: () => ({
      email: null
  }),
  created() {
      if (this.value) {
          this.email = this.value;
      }
  },
  methods: {
    handleInput (e) {
        this.email = e.target.value;
this.$emit('input', this.email); } }, name: 'email-input' } </script>

และเมื่อนำไปใช้ก็จะหน้าตาแบบนี้

<email-input v-model="email"></email-input>

แล้วถ้าเราต้องการใช้ props หรือ event อื่นล่ะ?

ถ้าต้องการใช้ props ชื่ออื่นหรือ event อื่นเป็นตัวผูก v-model สามารถทำได้โดยเพิ่ม property ชื่อว่า model ขึ้นมากำหนดใน component ที่เราสร้างขึ้น
<template>
  <input type="email" @input="handleInput" />
</template>

<script>
export default {
  props: ['myInput'],
  model: {
      prop: 'myInput',
      event: 'blur'
  },
  data: () => ({
      email: null
  }),
  created() {
      if (this.myInput) {
          this.email = this.myInput;
      }
  },
  methods: {
    handleInput (e) {
        this.email = e.target.value;
this.$emit('blur', this.email); } }, name: 'email-input' } </script>

ในตัวอย่างด้านบนผมเปลี่ยน prop เป็น myInput และ event เป็น blue ตามที่เขียนใน model property เผื่อไว้ใช้เพื่อป้องกันการ conflict กับโค้ดอื่น ๆ ที่อาจเกิดขึ้นได้

อ้างอิง: How To Add v-model Support to Custom Vue.js Components | DigitalOcean

หมายเหตุ: ใน link ที่อ้างอิงเขาประกาศ prop ผิด ต้องเป็น props นะครับ

ความคิดเห็น

แสดงความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

[Blue Archive] รีวิวชินัตสึ (Chinatsu)

[Blue Archive] รีวิวมารินะ (Marina)

[Blue Archive] รวมล็อบบี้ความทรงจำ (Live2D)

[Blue Archive] รีวิวยูกะชุดพละ (Yuuka Gym)

[Blue Archive] รีวิวโฮชิโนะ (Hoshino)