Vue.js เริ่มต้น ตอน5 (ทําความรู้จักกับ Props)

Jun 8, 2018 01:14 · 584 words · 3 minute read vue.js JavaScript

หลังจากที่เราเรียนรู้ Component กันไปแล้ว ถ้ายังจํากันได้ภายใน Component มี Option ตัวนึงชื่อว่า Props ซึ่งมีหน้าที่ รับข้อมูลจากภายนอก Component เข้ามาใช้งานภายใน Component โดยจะรับข้อมูลผ่านทาง Attribute การใช้งาน Props สามารถใช้งานได้หลายรูปแบบ เราจะมาเรียนรู้ไปทีละแบบนะครับ

Basic use

MyComponent.vue

<template>
  <div>
      {{ msg }}
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  props: [
    'msg'
  ]
}
</script>

เรียกใช้งาน Component

<MyComponent msg="This is a message."/>

Prop Casing (camelCase vs kebab-case)

โดยปกติ HTML Attribute name เป็นแบบ case-insensitive หมายความว่า ไม่ว่าจะเป็นตัวพิมพ์เล็กหรือ ตัวพิมพ์ใหญ่จะมองว่าเป็นตัวเดียวกัน เพื่อให้เห็นภาพ ดูตัวอย่างนี้ครับ MyComponent.vue

<template>
  <div>
      {{ MyMessage }}
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  props: [
    'MyMessage'
  ]
}
</script>

เราสามารถเรียกใช้งาน Component ได้แบบนี้

<MyComponent my-message="This is a message."/>

จะเห็นว่าตอนที่เราประกาศ Props เราประกาศเป็นแบบ camelCase แต่ตอนเราเรียกใช้ Component เราสามารถส่งข้อมูลผ่าน Props โดยระบุ Attribute เป็นแบบ kebab-case ได้

Static and Dynamic Props

การส่งข้อมูลผ่าน Props แบบ Static

<blog-post title="My journey with Vue"></blog-post>

การส่งข้อมูลผ่าน Props แบบ Dynamic ซึ่งข้อมูลสามารถเปลี่ยนแปลงไปตามการทํางานของโปรแกรม เราจะใช้ v-bind: เพิ่มเข้าไปหน้าของชื่อ Props ประมาณนี้

<blog-post v-bind:title="post.title"></blog-post>

การส่งข้อมูลชนิดต่างๆ Passing a Number ใช้ v-bind เพื่อบอกว่า เป็น expression ไม่ใช้ String

<blog-post v-bind:likes="42"></blog-post>

<!-- Dynamically -->
<blog-post v-bind:likes="post.likes"></blog-post>

Passing a Boolean ใช้ v-bind เพื่อบอกว่า เป็น expression ไม่ใช้ String

<!-- ถ้าเรียกแบบนี้หมายความว่า favorited เป็น true -->
<blog-post favorited></blog-post>

<!-- Even though `false` is static, we need v-bind to tell Vue that -->
<!-- this is a JavaScript expression rather than a string.          -->
<base-input v-bind:favorited="false">

<!-- Dynamically assign to the value of a variable. -->
<base-input v-bind:favorited="post.currentUserFavorited">

Passing an Array ใช้ v-bind เพื่อบอกว่า เป็น expression ไม่ใช้ String

<!-- Even though the array is static, we need v-bind to tell Vue that -->
<!-- this is a JavaScript expression rather than a string.            -->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

<!-- Dynamically assign to the value of a variable. -->
<blog-post v-bind:comment-ids="post.commentIds"></blog-post>

Passing an Object ใช้ v-bind เพื่อบอกว่า เป็น expression ไม่ใช้ String

<!-- Even though the object is static, we need v-bind to tell Vue that -->
<!-- this is a JavaScript expression rather than a string.             -->
<blog-post v-bind:comments="{ id: 1, title: 'My Journey with Vue' }"></blog-post>

<!-- Dynamically assign to the value of a variable. -->
<blog-post v-bind:post="post"></blog-post>

Passing the Properties of an Object เราสามารถสร้างเป็น Object ของ Props ที่เราต้องการส่งข้อมูล แล้วส่งไปที่เดียวได้เลย กรณีที่มี Props จํานวนมากๆ จะได้ไม่ต้องเขียนยาวๆ ตัวอย่างประมาณนี้

//javascript
post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>

จากตัวอย่างด้านบนจะมีความหมายเดียวกันกับ Code ด้านล่าง

<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

One-Way Data Flow

โดยปกติการส่งข้อมูลผ่าน Props ไปให้ Child component แล้วเมื่อ Child component เปลี่ยนแปลงข้อมูลดังกล่าว จะส่งผลไปยัง Parent component ด้วย หรือในทางกลับกันเมื่อข้อมูลใน Parent conponent เปลี่ยนแปลง ก็จะส่งผลมายัง Child ด้วยเช่นกัน ดังนั้น ถ้าต้องการเปลี่ยนแปลงข้อมูลที่รับมาจาก Parent component โดยที่ไม่ต้องการให้กระทบกัน Parent component สามารถทําได้ดังนี้ สามารถทําได้สองแบบดังนี้ แบบที่ 1

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

แบบที่ 2

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

กรณีที่ ส่งข้อมูลที่เป็น Object จะส่งเป็นแบบ By Reference หมายความว่า เมื่อ Component แม่ เปลี่ยนแปลงข้อมูล จะส่งผลมายัง Component ลูกด้วย

Prop Validation

Props สามารถกําหนดประเภทของข้อมูลที่รับเข้ามาได้ เช่น ต้องการเป็น ตัวเลข, ตัวอักษร ฯลฯ รวมถึงกําหนดค่า default ด้วย สามารถระบุได้ตามตัวอย่างนี้ครับ

props: {
    // Basic type check (`null` matches any type)
    propA: Number,
    // Multiple possible types
    propB: [String, Number],
    // Required string
    propC: {
      type: String,
      required: true
    },
    // Number with a default value
    propD: {
      type: Number,
      default: 100
    },
    // Object with a default value
    propE: {
      type: Object,
      // Object or array defaults must be returned from
      // a factory function
      default: function () {
        return { message: 'hello' }
      }
    },
    // Custom validator function
    propF: {
      validator: function (value) {
        // The value must match one of these strings
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }

Type Checks

  • String
  • Number
  • Boolean
  • Function
  • Object
  • Array
  • Symbol

นอกจากนี้เราสามารถสร้าง type ขึ้นมาเองได้ตามตัวอย่างนี้

function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

ตัวอย่างการใช้งาน

props: {
    author: Person
}

มาถึงตอนนี้เราได้เรียนรู้เรื่องการใช้งาน Props ในแบบต่างๆ รวมไปถึงการ Validation Props กันไปแล้วนะครับ ผมก็ขอจบไว้เพียงเท่านี้ครับ แล้วเจอกันบทความหน้า ขอบคุณครับ