0Pricing
Frontend Academy · บทเรียน

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 change

watchEffect()

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 ให้เรียกใช้ฟังก์ชันนี้เพื่อหยุดการเฝ้าดู ใน