คำสั่ง v-model

   อัปเดตล่าสุด Feb. 15, 2024

v-model ใน Vue 3 คือ คำสั่งสำคัญที่ช่วยให้สามารถผูกข้อมูลระหว่างอินพุตแบบสองทาง (2-Way Data Binding)  นั่นหมายความว่า เมื่อผู้ใช้ป้อนข้อมูลในอินพุต ข้อมูลนั้นจะอัปเดตในโมเดล และในทางกลับกัน เมื่อข้อมูลเปลี่ยน ค่าที่แสดงในอินพุตก็จะอัปเดตตาม โดยส่วนใหญ่หรือปกติแล้วมักจะใช้ในฟอร์ม 


การใช้งาน v-model

<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>


จากโค้ดด้านบนเป็นส่วนหนึ่งของ Vue 3 Component ซึ่งใช้ Composition API และ Model-Based Reactivity 

  • สร้างตัวแปร firstName และ  lastName โดยใช้ฟังก์ชัน  defineModel()  จาก Model-Based Reactivity ซึ่งจะ track การเปลี่ยนแปลงข้อมูลภายในตัวแปรนี้
  • สร้างฟิลด์อินพุตชนิดข้อความ ผูกข้อมูลกับตัวแปร  firstName  ด้วย  v-model  เมื่อผู้ใช้พิมพ์ ข้อมูลจะอัปเดตใน  firstNameโดยอัตโนมัติ
  • สร้างฟิลด์อินพุตผูกข้อมูลกับตัวแปร  lastName 


โค้ดนี้สร้างคอมโพเนนต์ที่มี 2 ฟิลด์อินพุต ชื่อและนามสกุล เมื่อผู้ใช้พิมพ์ในแต่ละฟิลด์ ข้อมูลจะอัปเดตในตัวแปรที่กำหนดไว้ และสามารถนำข้อมูลเหล่านั้นไปใช้ในส่วนอื่นของคอมโพเนนต์ได้อย่างสะดวก โดยใช้ประโยชน์จาก Model-Based Reactivity ในการ track การเปลี่ยนแปลงข้อมูล


เทคนิคเพิ่มเติม

1. ใช้กับ Component อื่นๆ

ตัวอย่างนี้ เราสร้างคอมโพเนนต์ MyCounter ที่ทำหน้าที่เป็นตัวนับ ตัวแปร count ในคอมโพเนนต์หลักจะถูกผูกข้อมูลกับคอมโพเนนต์ MyCounter ผ่าน v-model เมื่อผู้ใช้กดปุ่ม +/- ใน MyCounter ค่าของ count จะถูกอัปเดตทั้งในคอมโพเนนต์ MyCounter และคอมโพเนนต์หลัก

<template>
<MyCounter v-model="count" />
</template>

<script setup>
import MyCounter from "./MyCounter.vue";
let count = 0;
</script>


 MyCounter.vue 

<template>
<button @click="count++">+</button>
<span>{{ count }}</span>
<button @click="count--">-</button>
</template>

<script>
export default {
props: {
modelValue: Number,
},
emits: ['update:modelValue'],
watch: {
modelValue(newValue) {
this.$emit('update:modelValue', newValue);
},
},
};
</script>


2. ปรับแต่ง modifiers

v-model สามารถใช้ร่วมกับ modifiers เพื่อปรับเปลี่ยนพฤติกรรม เช่น  .trim  ตัดช่องว่าง .number  สำหรับแปลงเป็นตัวเลข

<template>
<input type="text" v-model.trim="message" placeholder="Enter a message" />
<p>Your message (trimmed): {{ message }}</p>
</template>

<script setup>
let message = "";
</script>


3. จัดการสถานะหลายค่า

ตัวอย่างนี้แสดงข้อมูลในตัวแปร items โดยผู้ใช้สามารถเพิ่มไอเท็มใหม่ได้โดยพิมพ์ชื่อในช่อง  newItemName  และกดปุ่ม "เพิ่ม" ฟังก์ชัน  addItem()  จะเพิ่มไอเท็มใหม่ลงใน items และเคลียร์ค่า  newItemName 

ตัวอย่างการใช้ watch สำหรับ two-way data binding ยังเป็นคุณสมบัติทดลองใน Vue 3 ควรพิจารณาใช้วิธีอื่นที่แนะนำ เช่น methods หรือ computed properties กับ emit events สำหรับการส่งข้อมูล
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
<button @click="removeItem(item.id)">Remove</button>
</li>
</ul>
<input type="text" v-model="newItemName" placeholder="Add item" />
<button @click="addItem">Add</button>
</template>

<script setup>
let items = [
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
];
let newItemName = "";

const addItem = () => {
if (newItemName) {
items.push({ id: Date.now(), name: newItemName });
newItemName = "";
}
};

const removeItem = (id) => {
items = items.filter((item) => item.id !== id);
};
</script>


Best Practice สำหรับ v-model

  • เลือกชนิดข้อมูลของอินพุตให้เหมาะสม
  • ใช้ modifiers อย่างพอดี ไม่เยอะเกินไป
  • แยกตรรกะการจัดการข้อมูลออกจากเทมเพลต
  • ใช้ v-model อย่างเหมาะสม ไม่ใช้กับทุกองค์ประกอบ
  • ทดสอบการผูกข้อมูลอย่างละเอียด



คอร์สเรียนแนะนำ

Mastering Vue.js 101

เรียนรู้การใช้งาน Vue.js ซึ่งเป็นหนึ่งใน JavaScript Front-end frameworks ท…