Dark mode
Composition API Lifecycle Hooks
Lifecycle Hook | การทำงาน | เวลาที่เหมาะสมในการใช้งาน |
---|---|---|
onBeforeMount() | ทำงานก่อนที่ component จะถูกแสดงผล | เตรียมข้อมูลก่อนการแสดงผล |
onMounted() | ทำงานหลังจาก component ถูกแสดงผลเรียบร้อย | เข้าถึง DOM, เริ่มดึงข้อมูลจาก API |
onBeforeUpdate() | ทำงานก่อนที่ component จะถูก re-render | จัดการข้อมูลก่อนการอัปเดต UI |
onUpdated() | ทำงานหลังจาก component ถูก re-render | ทำงานกับ DOM หลังการอัปเดต |
onBeforeUnmount() | ทำงานก่อนที่ component จะถูกทำลาย | เตรียมการก่อนที่ component จะหายไป |
onUnmounted() | ทำงานหลังจาก component ถูกทำลาย | ทำความสะอาด resources, event listeners |
onErrorCaptured() | จับข้อผิดพลาดจาก child components | จัดการข้อผิดพลาดในแอปพลิเคชัน |
onRenderTracked() | ติดตามสาเหตุที่ทำให้ component render | การ debug ใน development mode |
onRenderTriggered() | ติดตามตัวกระตุ้นที่ทำให้เกิดการ render | การ debug ใน development mode |
onActivated() | ทำงานเมื่อ component ถูกเรียกใช้งานอีกครั้ง | เริ่มต้นการทำงานที่หยุดไปใน <keep-alive> |
onDeactivated() | ทำงานเมื่อ component ถูกซ่อนไว้ | หยุดการทำงานชั่วคราวใน <keep-alive> |
onServerPrefetch() | ทำงานก่อนการ render ฝั่ง server | รอให้การดึงข้อมูลเสร็จก่อน hydration |
ช่วงเวลาหลักๆ และ Hooks ที่เกี่ยวข้อง (Composition API)
เราจะเน้นไปที่ Hooks ที่ใช้บ่อยและสำคัญนะครับ
1. ช่วงเตรียมตัวและแสดงผล (Mounting)
เป็นช่วงที่ Vue กำลังเตรียม Component และนำไปแสดงผลบนหน้าจอ
onBeforeMount()
:- เมื่อไหร่: ก่อนที่ Component จะถูกวาดลงบนหน้าจอ (DOM ยังไม่มี) แต่ทุกอย่างเตรียมพร้อมแล้ว (Template ถูก compile แล้ว)
- เปรียบเทียบ: เหมือนนักแสดงเตรียมตัวอยู่หลังเวที ทุกอย่างพร้อม แต่ยังไม่ได้ออกไปแสดง
- ใช้ทำอะไร: เหมาะกับการเตรียมข้อมูลบางอย่างที่ไม่ต้องรอ DOM
- vue
<script setup lang="ts"> import { onBeforeMount } from "vue"; onBeforeMount(() => { console.log("กำลังจะแสดงผล Component นี้แล้วนะ (แต่ยังไม่เห็นบนจอ)"); // อาจจะเตรียมข้อมูลบางอย่างตรงนี้ }); </script>
onMounted()
(ใช้บ่อยมาก!):- เมื่อไหร่: หลังจากที่ Component ถูกวาดลงบนหน้าจอเรียบร้อยแล้ว (เข้าถึง DOM ได้แล้ว)
- เปรียบเทียบ: เหมือนนักแสดงออกมายืนบนเวทีแล้ว ผู้ชมเห็นแล้ว
- ใช้ทำอะไร:
- ดึงข้อมูลจาก API มาแสดงผล
- ทำงานกับ DOM element โดยตรง (เช่น สั่ง focus input, ใช้ library ที่ต้องผูกกับ element)
- ตั้งค่า event listeners ต่างๆ
- vue
<script setup lang="ts"> import { onMounted, ref } from "vue"; const data = ref(null); const elementRef = ref<HTMLElement | null>(null); onMounted(async () => { console.log("Component แสดงผลบนหน้าจอเรียบร้อย!"); // 1. ดึงข้อมูลจาก API try { const response = await fetch("https://api.example.com/data"); data.value = await response.json(); console.log("ข้อมูลจาก API:", data.value); } catch (error) { console.error("ดึงข้อมูลไม่สำเร็จ:", error); } // 2. ทำงานกับ DOM (ถ้าจำเป็น) if (elementRef.value) { elementRef.value.focus(); // สั่งให้ input นี้ focus อัตโนมัติ console.log("เข้าถึง DOM:", elementRef.value.tagName); } }); </script> <template> <div> <h2>ข้อมูล:</h2> <pre v-if="data">{{ data }}</pre> <p v-else>กำลังโหลด...</p> <input ref="elementRef" placeholder="Input นี้จะ focus อัตโนมัติ" /> </div> </template>
2. ช่วงมีการเปลี่ยนแปลง (Updating)
เกิดขึ้นเมื่อข้อมูล (reactive state) ใน Component เปลี่ยนแปลง ทำให้ Vue ต้องวาดหน้าจอใหม่ (re-render)
onBeforeUpdate()
:- เมื่อไหร่: ทันทีที่ข้อมูลเปลี่ยน แต่ ก่อน ที่หน้าจอจะอัปเดตตามข้อมูลใหม่
- เปรียบเทียบ: เหมือนกำลังจะปรับปรุงบ้าน แต่ยังไม่ได้ลงมือทาสีใหม่
- ใช้ทำอะไร: เหมาะกับการเข้าถึงสถานะ ก่อน การอัปเดต DOM เช่น อ่านค่า scroll position ปัจจุบัน ก่อนที่ list จะยาวขึ้น/สั้นลง
- vue
<script setup lang="ts"> import { onBeforeUpdate, onUpdated, ref } from "vue"; const message = ref("ข้อความเริ่มต้น"); onBeforeUpdate(() => { console.log("กำลังจะอัปเดต DOM!", message.value); // สามารถเข้าถึงค่า message.value ตัวใหม่ได้แล้ว // แต่ DOM บนหน้าจอยังเป็นค่าเก่าอยู่ }); // ดู onUpdated ประกอบเพื่อเห็นความต่าง </script>
onUpdated()
:- เมื่อไหร่: หลังจากที่ข้อมูลเปลี่ยน และหน้าจออัปเดตตามข้อมูลใหม่เรียบร้อยแล้ว
- เปรียบเทียบ: เหมือนทาสีบ้านเสร็จแล้ว เห็นสีใหม่แล้ว
- ใช้ทำอะไร: ทำงานกับ DOM หลังจาก ที่มันอัปเดตแล้ว เช่น สั่ง scroll ไปที่ element ใหม่ที่เพิ่งเพิ่มเข้ามา
- vue
<script setup lang="ts"> import { onUpdated, ref } from "vue"; const message = ref("ข้อความเริ่มต้น"); const counter = ref(0); function updateMessage() { counter.value++; message.value = `ข้อความอัปเดตครั้งที่ ${counter.value}`; } onUpdated(() => { console.log("DOM อัปเดตเรียบร้อยแล้ว!", message.value); // DOM บนหน้าจอเป็นค่าใหม่แล้ว // เหมาะกับการทำงานกับ DOM หลังการอัปเดต }); </script> <template> <div> <p>{{ message }}</p> <button @click="updateMessage">อัปเดตข้อความ</button> </div> </template>
3. ช่วงเก็บกวาดและจากไป (Unmounting)
เกิดขึ้นเมื่อ Component กำลังจะถูกลบออกจากหน้าจอ (เช่น เปลี่ยนหน้า, ใช้ v-if
แล้วเป็น false)
onBeforeUnmount()
:- เมื่อไหร่: ก่อนที่ Component จะถูกลบออกไป (Component ยังทำงานได้ปกติ)
- เปรียบเทียบ: เหมือนกำลังจะย้ายบ้าน เริ่มเก็บของ แต่ยังอยู่ในบ้านหลังเดิม
- ใช้ทำอะไร: อาจจะใช้ถามยืนยัน หรือบันทึกสถานะบางอย่างก่อนจากไป
- vue
<script setup lang="ts"> import { onBeforeUnmount } from "vue"; onBeforeUnmount(() => { console.log("Component กำลังจะถูกลบแล้วนะ!"); // ยังเข้าถึง property, method ต่างๆ ได้ }); </script>
onUnmounted()
(สำคัญมากสำหรับการ Cleanup):- เมื่อไหร่: หลังจากที่ Component ถูกลบออกจากหน้าจอเรียบร้อยแล้ว
- เปรียบเทียบ: เหมือนย้ายออกจากบ้านไปแล้ว บ้านว่างแล้ว
- ใช้ทำอะไร (สำคัญมาก!): ทำความสะอาดสิ่งที่เคยสร้างไว้ตอน
onMounted
เพื่อป้องกัน memory leaks- ยกเลิก
setInterval
หรือsetTimeout
- ลบ event listeners ที่สร้างเอง (
window.addEventListener
) - ยกเลิกการเชื่อมต่อต่างๆ (เช่น WebSocket)
- ยกเลิก
- vue
<script setup lang="ts"> import { onMounted, onUnmounted, ref } from "vue"; const seconds = ref(0); let timerId: number | null = null; // ใช้ number สำหรับ Node.js/Browser Timeout ID function handleScroll() { console.log("กำลัง scroll:", window.scrollY); } onMounted(() => { console.log("เริ่มตั้งเวลา และ lắng nghe scroll"); // 1. ตั้งเวลา timerId = setInterval(() => { seconds.value++; console.log(`ผ่านไป ${seconds.value} วินาที`); }, 1000); // 2. เพิ่ม event listener window.addEventListener("scroll", handleScroll); }); onUnmounted(() => { console.log("เก็บกวาด! ยกเลิก timer และ scroll listener"); // 1. ยกเลิก timer (สำคัญมาก!) if (timerId !== null) { clearInterval(timerId); } // 2. ลบ event listener (สำคัญมาก!) window.removeEventListener("scroll", handleScroll); }); </script> <template> <div>เวลาผ่านไป: {{ seconds }} วินาที</div> <div style="height: 2000px; background: lightgray; margin-top: 20px"> Scroll ลงมาดู Console Log </div> </template>
Hooks อื่นๆ ที่อาจเจอ
onErrorCaptured()
:- เมื่อไหร่: เมื่อเกิด Error ใน Component ลูก (Child Component)
- ใช้ทำอะไร: ดักจับ Error จากลูกๆ มาจัดการที่ Component แม่, ส่ง Error log ไปที่ระบบ Monitoring
onRenderTracked()
/onRenderTriggered()
:- เมื่อไหร่: ตอนที่ Component render หรือ re-render (เฉพาะตอน Development Mode)
- ใช้ทำอะไร: Debug ว่า ทำไม Component ถึง render ใหม่, อะไรเป็นตัวกระตุ้น มีประโยชน์ตอนหา Performance Bottlenecks
- Hooks สำหรับ
<KeepAlive>
(onActivated()
,onDeactivated()
):- ใช้กับ Component ที่ถูกหุ้มด้วย
<KeepAlive>
(Component ที่ไม่ถูกทำลายเมื่อสลับไปมา) onActivated
: ทำงานเมื่อ Component ถูกแสดงอีกครั้ง (หลังจากเคย Deactivate)onDeactivated
: ทำงานเมื่อ Component ถูกซ่อน (แต่ยังไม่ถูกทำลาย)
- ใช้กับ Component ที่ถูกหุ้มด้วย
- Hook สำหรับ Server-Side Rendering (
onServerPrefetch()
):- เมื่อไหร่: ทำงาน เฉพาะ ตอน Render บน Server (SSR) ก่อนที่ Component จะถูกส่งไปให้ Client
- ใช้ทำอะไร: ดึงข้อมูลที่จำเป็นให้เสร็จ ก่อน ที่จะ Render หน้าเว็บฝั่ง Server
สรุปตาราง Lifecycle Hooks (Composition API)
Lifecycle Hook | ทำงานเมื่อไหร่? | เหมาะสำหรับ |
---|---|---|
onBeforeMount | ก่อนแสดงผล (DOM ยังไม่มี) | เตรียมข้อมูลพื้นฐาน |
onMounted | หลังแสดงผล (DOM พร้อมใช้) | ดึงข้อมูล API, จัดการ DOM, ตั้งค่า Listener |
onBeforeUpdate | ข้อมูลเปลี่ยน ก่อน DOM อัปเดต | อ่านสถานะ DOM ก่อนการเปลี่ยนแปลง |
onUpdated | ข้อมูลเปลี่ยน หลัง DOM อัปเดต | จัดการ DOM หลังการอัปเดต |
onBeforeUnmount | ก่อนถูกลบ (ยังทำงานได้) | เตรียมการก่อนลบ, ถามยืนยัน |
onUnmounted | หลังถูกลบ | ทำความสะอาด (สำคัญ!), ยกเลิก timer/listener |
onErrorCaptured | เกิด Error ใน Component ลูก | จัดการ Error รวมศูนย์ |
onRenderTracked | Component ถูก Track เพื่อ Render (Dev) | Debug การ Render |
onRenderTriggered | Component ถูก Trigger ให้ Render (Dev) | Debug การ Render |
onActivated | Component ใน <KeepAlive> ถูกแสดง | เริ่มการทำงานใหม่ (หลัง Deactivate) |
onDeactivated | Component ใน <KeepAlive> ถูกซ่อน | หยุดการทำงานชั่วคราว |
onServerPrefetch | ก่อน Render ฝั่ง Server (SSR) | ดึงข้อมูลให้เสร็จก่อนส่ง HTML |
หวังว่าคำอธิบายและตัวอย่างใหม่นี้จะช่วยให้เข้าใจเรื่อง Lifecycle Hooks ใน Vue Composition API ได้ง่ายขึ้นนะครับ!