Dark mode
ต่อไปนี้คือเนื้อหาเกี่ยวกับ Vue API ในหัวข้อที่คุณระบุ โดยใช้ภาษาที่เข้าใจง่าย กระชับ และเป็นมิตร พร้อมตัวอย่างโค้ดที่ชัดเจน:
Setup
Basic Usage
<script setup>
เป็นวิธีเขียน Vue component ที่ง่ายและกระชับ โดยตัวแปรและฟังก์ชันที่กำหนดจะพร้อมใช้งานใน <template>
ทันที.
vue
<script setup>
const message = 'สวัสดี Vue!';
</script>
<template>
<div>{{ message }}</div>
</template>
Accessing Props
ใช้ defineProps
เพื่อรับและใช้งาน props ที่ส่งมาจาก parent component.
vue
<script setup>
const props = defineProps(['title']);
</script>
<template>
<h1>{{ props.title }}</h1>
</template>
Setup Context
เข้าถึงบริบทของ component เช่น attrs
, slots
, หรือ emit
ผ่าน defineEmits
และ useAttrs
/useSlots
.
vue
<script setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
const emit = defineEmits(['update']);
</script>
<template>
<button @click="emit('update')">คลิก</button>
</template>
Usage with Render Functions
ใช้ <script setup>
ร่วมกับ render function เพื่อสร้าง UI ด้วย JavaScript แทน <template>
.
vue
<script setup>
import { h } from 'vue';
const render = () => h('div', {}, 'สร้างด้วย render function');
</script>
Reactivity Core
ref()
สร้างตัวแปร reactive ที่เก็บค่าและอัปเดต UI เมื่อเปลี่ยนแปลง.
vue
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
computed()
สร้างค่าที่คำนวณจาก reactive data และอัปเดตเมื่อข้อมูลต้นทางเปลี่ยน.
vue
<script setup>
import { ref, computed } from 'vue';
const count = ref(1);
const double = computed(() => count.value * 2);
</script>
<template>
<div>{{ double }}</div>
</template>
reactive()
สร้างอ็อบเจ็กต์ reactive ที่ทุก property จะถูกติดตามการเปลี่ยนแปลง.
vue
<script setup>
import { reactive } from 'vue';
const state = reactive({ count: 0 });
</script>
<template>
<button @click="state.count++">{{ state.count }}</button>
</template>
readonly()
สร้างอ็อบเจ็กต์หรือ ref ที่อ่านได้อย่างเดียว ป้องกันการแก้ไขข้อมูล.
vue
<script setup>
import { ref, readonly } from 'vue';
const original = ref(1);
const readOnly = readonly(original);
</script>
<template>
<div>{{ readOnly }}</div> <!-- ไม่สามารถแก้ไข readOnly ได้ -->
</template>
watchEffect()
รันฟังก์ชันเมื่อ reactive data ที่ใช้งานในนั้นเปลี่ยน โดยเริ่มรันทันที.
vue
<script setup>
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => console.log(`count: ${count.value}`));
</script>
watchPostEffect()
เหมือน watchEffect
แต่รันหลังจาก DOM อัปเดตเสร็จ (เหมาะกับการจัดการ DOM).
vue
<script setup>
import { ref, watchPostEffect } from 'vue';
const count = ref(0);
watchPostEffect(() => console.log('DOM อัปเดตแล้ว'));
</script>
watchSyncEffect()
เหมือน watchEffect
แต่รันแบบ synchronous ทันทีที่ข้อมูลเปลี่ยน.
vue
<script setup>
import { ref, watchSyncEffect } from 'vue';
const count = ref(0);
watchSyncEffect(() => console.log('เปลี่ยนทันที'));
</script>
watch()
ดูการเปลี่ยนแปลงของข้อมูลที่ระบุ และรัน callback พร้อมค่านเก่าและใหม่.
vue
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newVal, oldVal) => {
console.log(`จาก ${oldVal} เป็น ${newVal}`);
});
</script>
onWatcherCleanup()
จัดการการ cleanup ใน watch
หรือ watchEffect
เพื่อป้องกัน memory leak.
vue
<script setup>
import { ref, watchEffect, onWatcherCleanup } from 'vue';
const count = ref(0);
watchEffect(() => {
const timer = setInterval(() => console.log(count.value), 1000);
onWatcherCleanup(() => clearInterval(timer));
});
</script>
Reactivity Utilities
isRef()
ตรวจสอบว่าค่าที่ส่งมาเป็น ref
หรือไม่.
vue
<script setup>
import { ref, isRef } from 'vue';
const count = ref(0);
console.log(isRef(count)); // true
console.log(isRef(0)); // false
</script>
unref()
ดึงค่าจาก ref
หรือส่งคืนค่าเดิมถ้าไม่ใช่ ref
.
vue
<script setup>
import { ref, unref } from 'vue';
const count = ref(1);
console.log(unref(count)); // 1
console.log(unref(2)); // 2
</script>
toRef()
แปลง property ของ reactive object เป็น ref
เพื่อใช้งานแยก.
vue
<script setup>
import { reactive, toRef } from 'vue';
const state = reactive({ count: 0 });
const countRef = toRef(state, 'count');
</script>
<template>
<div>{{ countRef }}</div>
</template>
toValue()
ดึงค่าจาก ref
, computed
, หรือ getter function ถ้าไม่ใช่จะคืนค่าเดิม.
vue
<script setup>
import { ref, toValue } from 'vue';
const count = ref(1);
console.log(toValue(count)); // 1
console.log(toValue(() => 2)); // 2
</script>
toRefs()
แปลงทุก property ของ reactive object เป็น ref
เพื่อใช้งานแยก.
vue
<script setup>
import { reactive, toRefs } from 'vue';
const state = reactive({ count: 0, name: 'Vue' });
const { count, name } = toRefs(state);
</script>
<template>
<div>{{ count }} - {{ name }}</div>
</template>
isProxy()
ตรวจสอบว่าค่าที่ส่งมาเป็น reactive หรือ readonly proxy หรือไม่.
vue
<script setup>
import { reactive, isProxy } from 'vue';
const state = reactive({ count: 0 });
console.log(isProxy(state)); // true
console.log(isProxy({})); // false
</script>
isReactive()
ตรวจสอบว่าค่าที่ส่งมาเป็น reactive object หรือไม่.
vue
<script setup>
import { reactive, isReactive } from 'vue';
const state = reactive({ count: 0 });
console.log(isReactive(state)); // true
</script>
isReadonly()
ตรวจสอบว่าค่าที่ส่งมาเป็น readonly object หรือไม่.
vue
<script setup>
import { readonly, isReadonly } from 'vue';
const state = readonly({ count: 0 });
console.log(isReadonly(state)); // true
</script>
Reactivity Advanced
shallowRef()
สร้าง ref
ที่ติดตามเฉพาะค่า .value
ไม่ติดตามการเปลี่ยนแปลงภายในอ็อบเจ็กต์.
vue
<script setup>
import { shallowRef } from 'vue';
const obj = shallowRef({ count: 0 });
obj.value.count = 1; // ไม่ trigger การอัปเดต
obj.value = { count: 2 }; // trigger การอัปเดต
</script>
triggerRef()
บังคับ trigger การอัปเดตของ shallowRef
เมื่อค่าเปลี่ยน.
vue
<script setup>
import { shallowRef, triggerRef } from 'vue';
const obj = shallowRef({ count: 0 });
obj.value.count = 1;
triggerRef(obj); // บังคับอัปเดต
</script>
customRef()
สร้าง ref
ที่กำหนดพฤติกรรมการ get/set ได้เอง.
vue
<script setup>
import { customRef } from 'vue';
const myRef = customRef((track, trigger) => {
let value = 0;
return {
get() { track(); return value; },
set(newValue) { value = newValue; trigger(); }
};
});
</script>
shallowReactive()
สร้าง reactive object ที่ติดตามเฉพาะชั้นแรกของ properties.
vue
<script setup>
import { shallowReactive } from 'vue';
const state = shallowReactive({ obj: { count: 0 } });
state.obj.count = 1; // ไม่ trigger การอัปเดต
state.obj = { count: 2 }; // trigger การอัปเดต
</script>
shallowReadonly()
สร้าง readonly object ที่ป้องกันการแก้ไขเฉพาะชั้นแรก.
vue
<script setup>
import { shallowReadonly } from 'vue';
const state = shallowReadonly({ obj: { count: 0 } });
state.obj.count = 1; // แก้ไขได้
// state.obj = {}; // Error
</script>
toRaw()
ดึงค่า raw (ไม่ reactive) จาก reactive หรือ readonly object.
vue
<script setup>
import { reactive, toRaw } from 'vue';
const state = reactive({ count: 0 });
const raw = toRaw(state);
console.log(raw === state); // false
</script>
markRaw()
ทำเครื่องหมายอ็อบเจ็กต์ว่าไม่ให้กลายเป็น reactive.
vue
<script setup>
import { reactive, markRaw } from 'vue';
const raw = markRaw({ count: 0 });
const state = reactive({ data: raw });
console.log(state.data === raw); // true
</script>
effectScope()
สร้าง scope สำหรับจัดการ effect (เช่น watch
หรือ computed
) และสามารถหยุดทั้งหมดพร้อมกัน.
vue
<script setup>
import { effectScope, ref } from 'vue';
const scope = effectScope();
scope.run(() => {
const count = ref(0);
watch(count, () => console.log(count.value));
});
scope.stop(); // หยุดทุก effect
</script>
getCurrentScope()
ดึง effect scope ปัจจุบันที่กำลังทำงาน.
vue
<script setup>
import { effectScope, getCurrentScope } from 'vue';
const scope = effectScope();
scope.run(() => {
console.log(getCurrentScope()); // scope ปัจจุบัน
});
</script>
onScopeDispose()
กำหนด callback ที่จะรันเมื่อ effect scope ถูกทำลาย.
vue
<script setup>
import { effectScope, onScopeDispose } from 'vue';
const scope = effectScope();
scope.run(() => {
onScopeDispose(() => console.log('scope ถูกทำลาย'));
});
scope.stop();
</script>
Lifecycle Hooks
onMounted()
รันโค้ดเมื่อ component ถูก mount เข้า DOM.
vue
<script setup>
import { onMounted } from 'vue';
onMounted(() => console.log('Component mounted'));
</script>
onUpdated()
รันโค้ดเมื่อ component อัปเดต DOM หลังจาก reactive data เปลี่ยน.
vue
<script setup>
import { onUpdated } from 'vue';
onUpdated(() => console.log('Component updated'));
</script>
onUnmounted()
รันโค้ดเมื่อ component ถูก unmount ออกจาก DOM.
vue
<script setup>
import { onUnmounted } from 'vue';
onUnmounted(() => console.log('Component unmounted'));
</script>
onBeforeMount()
รันโค้ดก่อน component ถูก mount เข้า DOM.
vue
<script setup>
import { onBeforeMount } from 'vue';
onBeforeMount(() => console.log('Before mount'));
</script>
onBeforeUpdate()
รันโค้ดก่อน component อัปเดต DOM.
vue
<script setup>
import { onBeforeUpdate } from 'vue';
onBeforeUpdate(() => console.log('Before update'));
</script>
onBeforeUnmount()
รันโค้ดก่อน component ถูก unmount.
vue
<script setup>
import { onBeforeUnmount } from 'vue';
onBeforeUnmount(() => console.log('Before unmount'));
</script>
onErrorCaptured()
จับข้อผิดพลาดจาก child components และจัดการได้.
vue
<script setup>
import { onErrorCaptured } from 'vue';
onErrorCaptured((err) => {
console.log('Error:', err);
return false; // ป้องกันการ propagate
});
</script>
onRenderTracked()
รันเมื่อ reactive dependency ถูกติดตามใน render (ใช้สำหรับ debug).
vue
<script setup>
import { onRenderTracked } from 'vue';
onRenderTracked(({ key }) => console.log(`Tracked: ${key}`));
</script>
onRenderTriggered()
รันเมื่อ reactive dependency trigger การ render (ใช้สำหรับ debug).
vue
<script setup>
import { onRenderTriggered } from 'vue';
onRenderTriggered(({ key }) => console.log(`Triggered: ${key}`));
</script>
onActivated()
รันเมื่อ component ภายใน <KeepAlive>
ถูก activate.
vue
<script setup>
import { onActivated } from 'vue';
onActivated(() => console.log('Component activated'));
</script>
onDeactivated()
รันเมื่อ component ภายใน <KeepAlive>
ถูก deactivate.
vue
<script setup>
import { onDeactivated } from 'vue';
onDeactivated(() => console.log('Component deactivated'));
</script>
onServerPrefetch()
รันโค้ดในฝั่ง server เพื่อ prefetch ข้อมูลก่อน render (SSR).
vue
<script setup>
import { onServerPrefetch } from 'vue';
onServerPrefetch(async () => {
const data = await fetch('/api/data').then(res => res.json());
console.log(data);
});
</script>
Dependency Injection
provide()
จัดเตรียมข้อมูลให้ child components เข้าถึงได้ผ่าน inject
.
vue
<script setup>
import { provide } from 'vue';
provide('key', 'ค่าเริ่มต้น');
</script>
inject()
ดึงข้อมูลที่ parent จัดเตรียมไว้ด้วย provide
.
vue
<script setup>
import { inject } from 'vue';
const value = inject('key', 'ค่า default');
</script>
<template>
<div>{{ value }}</div>
</template>
hasInjectionContext()
ตรวจสอบว่ามี injection context หรือไม่ก่อนใช้ inject
.
vue
<script setup>
import { hasInjectionContext, inject } from 'vue';
if (hasInjectionContext()) {
const value = inject('key');
console.log(value);
}
</script>
Helpers
useAttrs()
เข้าถึง attributes ที่ไม่ใช่ props ใน component.
vue
<script setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
console.log(attrs); // { class: 'test', id: 'my-id' }
</script>
useSlots()
เข้าถึง slots ที่ parent ส่งมาให้ component.
vue
<script setup>
import { useSlots } from 'vue';
const slots = useSlots();
console.log(slots.default); // ฟังก์ชัน slot
</script>
useModel()
สร้าง v-model ที่กำหนดเองสำหรับ component.
vue
<script setup>
import { useModel } from 'vue';
const model = useModel('value', { default: '' });
</script>
<template>
<input v-model="model" />
</template>
useTemplateRef()
สร้าง ref เพื่อเข้าถึง DOM element ใน <template>
โดยใช้ ref
attribute.
vue
<script setup>
import { useTemplateRef } from 'vue';
const inputRef = useTemplateRef('myInput');
</script>
<template>
<input ref="myInput" />
</template>
useId()
สร้าง ID ที่ไม่ซ้ำกันสำหรับ component เพื่อใช้ใน accessibility หรือ DOM.
vue
<script setup>
import { useId } from 'vue';
const id = useId(); // เช่น vue-1
</script>
<template>
<div :id="id">Unique ID</div>
</template>
vue
<script setup>
import { ref, computed, reactive, readonly, watchEffect, watch, provide, inject } from 'vue';
// Setup Examples
const message = ref('สวัสดี Vue!');
const props = defineProps(['title']);
const emit = defineEmits(['update']);
// Reactivity Core
const count = ref(0);
const double = computed(() => count.value * 2);
const state = reactive({ count: 0 });
const readOnlyState = readonly(state);
watchEffect(() => console.log(`count: ${count.value}`));
watch(count, (newVal, oldVal) => console.log(`จาก ${oldVal} เป็น ${newVal}`));
// Dependency Injection
provide('key', 'ค่าเริ่มต้น');
const injectedValue = inject('key', 'ค่า default');
</script>
<template>
<div>
<h1>{{ message }}</h1>
<p>{{ props.title }}</p>
<button @click="count++">นับ: {{ count }} (Double: {{ double }})</button>
<p>State: {{ state.count }}</p>
<p>Injected: {{ injectedValue }}</p>
</div>
</template>
<style scoped>
div { font-family: Arial, sans-serif; }
button { padding: 8px; }
</style>