Vue.js การใช้งาน $refs และ nextTick

Vue.js การใช้งาน $refs และ nextTick

สำหรับ this.$refs นั้นก็เป็นอีก 1 ฟีเจอร์สำหรับเรียกใช้ DOM เมื่อวันที่ 12/07/60 ผมได้อ่านบทความของพี่คนนึงเขียนเรื่องนี้ไว้ครับ

**[Vue.js] ใช้ ref เรียก DOM แทน jQuery แบบเดิม


วันนี้เลยขอเขียนเพิ่มเติม this.$refs ในกรณีใช้ plugin หรือ lib ต่างๆด้วยเลยก่อนจะเริ่มก็ขอปูพื้นกันก่อนถ้าใครเข้าใจตรงนี้ หรือ อ่านบทความด้านบนแล้วข้ามไปได้เลยฮ่ะ ><

ในการ access DOM ของ HTML นั้นใน javascript เราทำแบบนี้

<input type="text" name="first_name" class="input_name" id="input_name">
// js
document.getElementsByClassName('input_name')[0].focus(); // เรียกผ่าน class
document.getElementById('input_name').focus(); // เรียกผ่าน id

แต่สำหรับใน vuejs แล้วมีสิ่งนึงที่มาแทนที่ class, id เดิมนั่นคือ ref=”Your Element Name” มีวิธีการใช้งานตามนี้ครับ

<input type="text" class="input-name" ref="input_name">
// js
this.$refs.input_name.focus() // ในกรณีใช้ CLI ช่วยสร้าง project
vm.$refs.input_name.focus()

ง่ายๆตาม style Vue.js แต่มันไม่ได้มีประโยชน์แค่นั้นเมื่อ Vue.js เค้าบอกว่ามันเร็วกว่าการ access ของ javascript ธรรมดานะในเมื่อเราเป็นสาวกของ Vue.js ก็ตามน้ำดีก็ดี(^^) แต่สิ่งหนึ่งที่จะมาแก้ไขปัญหาที่เกิดขึ้นเมื่อเราใช้ lib ต่างๆแล้วจะ access DOM ตัว Vue.js เนี่ยก็มีปัญหา lib ไม่ติด Render หน้าใหม่แล้วแตกวันนี้เลยขอเสนอฟีเจอร์(เสียงสูง…) อีก 1 ตัว

this.$nextTick( [callback] )

มันมาแก้ปัญหาตอนที่ DOM มันกำลัง update, render ใหม่, v-if ไว้, หรือ เกิดขึ้นเมื่อกดปุ่มบางอย่าง ทำให้เราไม่สามารถ access มันได้หรือตัว javascript, Jquery ไม่สามารถหา class หรือ id นี้ได้ก็เพราะมันยัง update DOM ไม่เสร็จฟังก์ชั่นนี้ก็จะทำหน้าที่เมื่อ DOM ถูก update แล้วจะเรียกให้ callback ทำงานในฟังก์ชั่นเอาไปใส่ใน Lifecycle Hooks หรือ Methods แบบนี้ครับ

mounted() {
 this.$nextTick(() => { // ES6 arrow function
  this.$refs.input_name.focus()
 })
}

หลายคนสงสัยว่าไอ้เจ้า Methods mounted() เค้าก็บอกอยู่ว่ามันคือการที่ DOM สร้างเสร็จแล้วนะแล้วทำไมต้องใช้ nextTick ก็เพราะตัว mounted() ไม่ได้การันตีว่ามันเสร็จแล้วจริงๆครับมันเสร็จบางส่วนที่พร้อมทำงานได้แต่ไม่ทั้งหมด…ใครที่ใช้ mounted() แล้วมันทำงานปกติก็โชคดีไปครับแต่ถ้าเมื่อไหร่ที่มันยังไม่เสร็จละก็อาจจะเกิด error ทั้งแผงเลยผมเคยเจอมาแล้วกับ Select2 ขอยกตัวอย่างดังนี้ครับ

// html
<select ref="lists">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>
// js
mounted() {
 this.$refs.lists.select2() 
 $(this.$refs.lists).select2() // หรือแบบ jquery
}

แบบนี้ใช้งานได้ปกติเลยครับแต่เมื่อไหร่ที่เรา update ตัว option ใน select หรือ get api ไปใส่ตัว Select2 แล้วมันยัง update ไม่เสร็จละก็มีโอกาศ error แน่นอน (เจอมากับตัว T T)ทางที่ดีเราควรใช้ nextTick เพื่อป้องกันปัญหาเหล่านี้ครับ

// html
<select ref="lists">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>
// js
mounted() {
 this.$nextTick(() => { // ES6 arrow function
  this.$refs.lists.select2() 
  $(this.$refs.lists).select2() // หรือแบบ jquery
 })
}

ให้ดีที่สุดคือเราใส่ไอ้เจ้าตัว nextTick ทุกครั้งที่ html เรามีการอัพเดท หรือ element นั้นๆต้องมีการ v-if ซ่อน แสดงผล บ่อยๆควรใช้ nextTick เพื่อยืนยันอีกครั้งว่ามันโหลดเสร็จแล้วจริงๆนะ..

Referrence

https://medium.com/@Kurozakizz/vue-js-%E0%B9%83%E0%B8%8A%E0%B9%89-ref-%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%81-dom-%E0%B9%81%E0%B8%97%E0%B8%99-jquery-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B9%80%E0%B8%94%E0%B8%B4%E0%B8%A1%E0%B9%86-24be5d137eaa

เกี่ยวกับผู้เขียน

ITTHIPAT

สวัสดีครับผม อิทธิพัทธ์ (เป้) ชอบหาเทคนิคต่างๆที่ทำให้ชีวิต Programmer ง่ายขึ้น ทั้ง Automate, Library ชอบทำ Blog และ Video ถ้ามีเวลานะ!

ขอบคุณทุกคนที่ติดตาม และอ่านบทความของผมครับ ผมหวังว่าความรู้ที่เขียนขึ้นในเว็บไซต์นี้จะช่วยทุกท่านได้ไม่มากก็น้อย 

Scroll to Top