computed() และ watch()
คำนวณค่าแบบประเมินเมื่อจำเป็นด้วย computed() ตอบสนองต่อการเปลี่ยนแปลงของสถานะด้วย watch() และ watchEffect() และควบคุมจังหวะการ flush
computed() และ watch() เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
computed() ใน Composition API
computed(fn) สร้าง ref รีแอกทีฟแบบอ่านอย่างเดียว ซึ่งคำนวณค่าจากแหล่งข้อมูลรีแอกทีฟอื่น ๆ โดยมีการแคชค่าไว้ — getter จะทำงานอีกครั้งเฉพาะเมื่อสิ่งที่พึ่งพาเปลี่ยนแปลง
<script setup>
import { ref, computed } from 'vue';
const items = ref([{ price: 10 }, { price: 20 }, { price: 30 }]);
const tax = ref(0.1);
const subtotal = computed(() => items.value.reduce((s, i) => s + i.price, 0));
const total = computed(() => subtotal.value * (1 + tax.value));
</script>computed() ที่เขียนค่าได้
ส่งอ็อบเจ็กต์ที่มี get และ set เพื่อสร้าง computed ที่เขียนค่าได้ setter จะจัดการการอัปเดต โดยทั่วไปจะสะท้อนการเปลี่ยนแปลงกลับไปยัง ref ต้นทาง
const firstName = ref('Alice');
const lastName = ref('Smith');
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (val: string) => {
[firstName.value, lastName.value] = val.split(' ');
}
});
fullName.value = 'Bob Jones'; // sets both refsพื้นฐานของ watch()
watch(source, callback) จะเรียก callback เมื่อ source เปลี่ยนแปลง โดย callback จะได้รับค่าใหม่และค่าเก่า
import { ref, watch } from 'vue';
const query = ref('');
watch(query, (newVal, oldVal) => {
console.log(`Changed from '${oldVal}' to '${newVal}'`);
searchAPI(newVal);
});การเฝ้าดู ref เทียบกับ reactive
เฝ้าดู ref ได้โดยตรง หากต้องการเฝ้าดูพร็อพเพอร์ตี้รีแอกทีฟ ให้ใช้ฟังก์ชัน getter () => state.prop
const count = ref(0);
watch(count, val => console.log('count:', val));
const state = reactive({ count: 0, name: '' });
watch(() => state.count, val => console.log('state.count:', val));การเฝ้าดูแบบลึก
ส่ง { deep: true } เพื่อเฝ้าดูการเปลี่ยนแปลงที่ซ้อนอยู่ภายในอ็อบเจ็กต์ ref
const user = ref({ name: 'Alice', address: { city: 'NY' } });
watch(user, (newUser) => {
console.log('user changed:', newUser);
}, { deep: true });การเฝ้าดูทันที
ส่ง { immediate: true } เพื่อเรียก callback ทันทีเมื่อเริ่มต้น ก่อนจะมีการเปลี่ยนแปลงใด ๆ ซึ่งมีประโยชน์เมื่อต้องการสร้างผลข้างเคียงด้วยค่าเริ่มต้น
watch(userId, async (id) => {
user.value = await fetchUser(id);
}, { immediate: true }); // runs once on setup, then on changewatchEffect()
watchEffect(fn) จะเรียก callback ทันที และเรียกซ้ำทุกครั้งที่สิ่งที่พึ่งพาแบบรีแอกทีฟซึ่งถูกใช้ภายในฟังก์ชันเปลี่ยนแปลง ไม่จำเป็นต้องระบุแหล่งข้อมูลอย่างชัดเจน
import { watchEffect } from 'vue';
watchEffect(() => {
// runs immediately and whenever query or page changes:
fetchResults(query.value, page.value);
});watchEffect เทียบกับ watch
watchEffect: ทำงานทันที ติดตามสิ่งที่พึ่งพาโดยอัตโนมัติ และไม่สามารถเข้าถึงค่าเก่าได้ ส่วน watch: ระบุแหล่งข้อมูลอย่างชัดเจน โดยค่าเริ่มต้นจะทำงานเมื่อมีการเปลี่ยนแปลง และเข้าถึงได้ทั้งค่าเก่าและค่าใหม่ ใช้ watchEffect สำหรับผลข้างเคียงแบบประกาศ และใช้ watch เมื่อต้องการควบคุมว่าจะให้ทำงานเมื่อใดหรือบ่อยเพียงใด
การหยุด Watcher
ทั้ง watch และ watchEffect จะส่งคืนฟังก์ชัน stop ให้เรียกใช้ฟังก์ชันนี้เพื่อหยุดการเฝ้าดู ใน