Template Refs อ้างอิงถึงองค์ประกอบ DOM ใน VueJS

บทความ เมื่อไม่กี่สัปดาห์ โดย Ninenik Narkdee
vuejs function refs template refs

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ vuejs function refs template refs

ดูแล้ว 156 ครั้ง


เนื้อหาต่อไปนี้เราจะมาดูบทความสั้นๆ เกี่ยวกับการใช้งาน Template Refs
หรือ Template References ซึ่ง ช่วยให้เราสามารถอ้างอิงถึงองค์ประกอบ 
DOM หรืออินสแตนซ์ของคอมโพเนนต์ในเทมเพลต HTML ได้โดยตรง 
 

การใช้งาน Template Refs ใน VueJS

ในเนื้อหาที่ผ่านๆ มาเราคุ้นเคยกับการนำค่าตัวแปร หรือ state ไปใช้งานใน template 
แล้วกรณีเราอยากอ้างอิงหรือเข้าถึง DOM ใน template เราจะสามารถทได้อย่างไร
ซึ่งใน vuejs จะใช้ ref สำหรับกำหนดใน DOM element ที่เราต้องการอ้างอิงถึงหรือใช้งาน
โดย ref เป็น attribute พิเศษชนิดหนึ่ง ที่คล้ายกับ key attribute ที่เราเคยได้พูดถึงมา
แล้วเกี่ยวกับการใช้งาน v-for ซึ่งจะคล้ายๆ กัน ที่ช่วยให้เราสามารถจัดการกับ element 
หรือ component ลูก ที่ต้องการได้ หลักจากที่ทำการ mounted หรือเพิ่มเข้าไปใน DOM
เรียบร้อยแล้ว ดูตัวอย่างโค้ดด้านล่างประกอบ
 
<script setup>
import { ref, onMounted } from 'vue'

// กำหนดตัวแปร ref เพื่อไว้อ้างอิง element
// ชื่อจะต้องตรงกับที่กำหนดใน template
const input = ref(null)

// หลักจากทำการ moundtd และอัปเดท DOM แล้วถึงจะเรียกใช้งานได้
onMounted(() => {
  // กำหนดให้ทำการ focus ไปที ่DOM ที่อ้างอิงผ่าน ref
  input.value.focus()
})
</script>

<template>
  <input ref="input" />
</template>
 
การเรียกใช้งาน template ref จะเรียกใช้งานได้หลังจากทำการ mounted เรียบร้อยแล้ว
ตัวแปรที่สร้างจาก ref ก็จะคล้ายตัวแปรที่เราสร้างทั่วไปคล้ายๆ กับทุกครั้งที่ผ่านมา เพียงถ้า
มีการนำไปเชื่อมกับ template ผ่าน ref attribute จะทำให้ตัวแปร กลาย DOM instance
ที่สามารถอ้างอิงถึง element นั้นๆ อย่างกรณี้ข้างต้น ค่า input ก็จะหมายถึงตัว input 
element ใน template แต่จะสามารถเรียกใช้งาน หลังจากทำการ mounted แล้ว จึงจะ
สามารถเข้าถึงคุณสมบัติต่างๆ ของ input ได้ ถ้าเราไปเรียกใช้งานก่อน จะเป็นใช้งาน object ref
ที่กำหนดเริ่มต้น 
 

ตัวอย่างการใช้งาน watchEffect กับ Template Refs 

เพื่อให้เห็นขั้นตอนการทำงานของ template refs เราจะใช้ตัวอย่างที่ทำงานร่วมกับ watchEffect
เพื่อจำลองการทำงาน ซึ่งจาก watchEffect ที่เราได้ศึกษามาแล้วในตอนที่ผ่าน เราจะทราบแล้วว่า
เมื่อมีการเรียกใช้งาน จะทำงานทันที 1 ครั้งหลังจาก mounted เสร็จโดยที่ข้อมูลไม่จำเป็นต้องมีการ
เปลี่ยนแปลง และหลังจากนั้นจะทำงานเมื่อข้อมูลมีการเปลี่ยนแปลงทุกครั้งปกติ ดูโค้ดตัวอย่างนี้
ประกอบการอธิบาย
 
<script setup>
import { ref, onMounted, watchEffect } from 'vue'

const myInput = ref(null); // Template Reference
const text = ref(''); // Reactive Data

// Computed property to reverse the text
const reversedText = ref('');

// WatchEffect to reactively update reversedText
watchEffect(() => {
  reversedText.value = text.value.split('').reverse().join('');
  console.log(`Input value: ${text.value}`);
  if (myInput.value) {
    console.log(`Input DOM element value: ${myInput.value.value}`);
  }
});
</script>

<template>
  <input ref="myInput" v-model="text" type="text" />
  <p>{{ reversedText }}</p>
</template>
 

ผลลัพธ์เมื่อโหลดครั้งแรก

 


 
 
จะเห็นว่าหลังจาก mounted เสร็จตัวฟังก์ชั่น watchEffect ก็จะทำงานทันที 1 ครั้งและแสดง
ข้อความใน console "Input value: " โดยค่าเริ่มต้นของ text เป็นค่า ว่าง และเนื่องจาก
การเข้ามาทำงานครั้งแรก ค่า myInput.value ยังเป็นค่า null จึงไม่เข้าเงื่อนไขแสดงข้อมูล
ที่สอง  หลังจากนั้น มีการกำหนด template refs ให้กับ input ทำให้ myInput ค่ามีการ
เปลี่ยนแปลง watchEffect จึงทำงานอีกครั้งตามเงื่อนไข เมื่อ state ที่กำหนดในไฟังก์ชั่นมี
การเปลี่ยนแปลง คือ myInput เดิมเป็นค่า null จากค่าเริ่มต้น ถูกเปลี่ยนเป็น input dom
จากการใช้งาน ref attribute ในการทำงานครั้งที่สอง จึงขึ้นข้อความ "Input value: " และ
"Input DOM element value: "  จากนั้นตัว watchEffect จะทำงานทุกครั้งที่มีการ
เปลี่ยนแปลงข้อมูลของ state ในฟังก์ชั่น ซึ่งก็รวมถึง text เมื่อเราพิมพ์ก็จะเกิดผลลัพธ์ดังนี้
 


 
 

 

การใช้งาน Template Refs ในรูปแบบฟังก์ชั่น (Function Refs)

ในกรณีที่เราต้องการจัดการกับ DOM ที่มีการทำงานที่ซับซ้อนขึ้น เราสามารถใช้การกำหนดใน
รูปแบบฟังก์ชั่นแทนการกำหนดแค่ข้อความ String โดยจะใช้ร่วมกับ v-bind:ref หรือ :ref
ตัวอย่างเช่น
 
<input :ref="(el) => { /* กำหนดให้ el เป็น property หรือ  ref object */ }">
 
โดยสามารถนำรูปแบบฟังก์ชั่น ไปเขียนแยกเป็นคำสั่งแล้วเรืยกใช้งานผ่านชื่อคำสั่งได้ ดูตัวอย่าง
ดังต่อไปนี้ประกอบ
 
<script setup>
import { ref, watch, onMounted } from 'vue'

const is_unmounted = ref(false)
const text = ref('');
const reversedText = ref('');

// กำหนดเป็นคำสั่ง ไว้ใช้งาน
const setMyInput = (el) => {
  if (el) {
    // เมื่อ element ถูกกำหนด
    console.log('Input element is mounted:', el);
    el.focus(); // ทำการ focus ที่ input element
  } else {
    // เมื่อ element ถูกลบออก
    console.log('Input element is unmounted');
  }
};

// เมื่อทำการพิมพ์ข้อความใหม่เข้าไป ตรวจสอบการเปลี่ยนแปลง
// แล้วทำการ reverse ข้อความที่พิมพ์
watch(text, (newValue) => {
  reversedText.value = newValue.split('').reverse().join('');
});

// จำลองการถอน element ออกจาก dom เพื่อทดสอบการ unmounted
setTimeout(()=>{
  is_unmounted.value = true
},10000)
</script>

<template>
  <input v-if="!is_unmounted" :ref="setMyInput" v-model="text"  />
  <p>{{ reversedText }}</p>
</template>
 
ผลลัพธ์เมื่อโหลดครั้งแรก
 


 
 
เมื่อเราพิมพ์คำว่า Hi เท่ากับเปลี่ยนแปลงค่าสองครั้งคือ H กับ i ตัว watch จึงทำงานเมื่อ
มีการเปลี่ยนแปลงข้อมูล 2 ครั้ง 
 


 
 
หลังครบ 10 วินาที ที่เราจำลองให้ นำ DOM ที่เราต้องการออก หรือจำลองการ unmounted
 


 
 
ตัวฟังก์ชั่น watch จะทำงานอีกครั้ง ก่อนถูกลบออกจากหน่วยความจำ หรือหยุดการทำงาน
โดยอัตโมัติเมื่อ DOM ถูกถอกออก
 
จะเห็นว่าการใช้งานแบบฟังก์ชั่น จะทำให้เราจัดการ DOM ได้มากขึ้นหรือกำหนดการทำงานที่
ซับซ้อนได้ง่าย Function Refs ช่วยให้การจัดการอ้างอิงถึงองค์ประกอบ DOM มีความยืดหยุ่น
และมีประสิทธิภาพมากขึ้น ช่วยให้โค้ดของเรามีความชัดเจนและสามารถจัดการกับสถานการณ์
ต่างๆ ได้อย่างง่ายดาย
 
เกี่ยวกับการใช้งาน template refs ทั้งที่แบบปกติ และแบบกำหนดเป็นฟังก์ชั่น ในเบื้องต้น
ก็จะมีประมาณนี้ ยังไม่การใช้งานร่วมกับ component ซึ่งตอนนี้เรายังไม่ได้รู้จักกับ component
เพิ่มเติมนัก ดังนั้นจึงไว้อัปเดทภายหลัง และบทความตอนนี้ เราจะมาทำความรู้จัก component
เบื้องต้นกัน รอติดตาม






กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ



ทบทวนบทความที่แล้ว









เนื้อหาที่เกี่ยวข้อง









URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ