본문 바로가기
지금, 개발하기/Vue

[Vue.js] compositionAPI에서 watch사용법

by Seaco :) 2024. 4. 21.

 

📌1. Composiotion API의 감시자

Vue.js에서 'watch'는 특정 데이터의 변화를 감지해서 원하는 코드를 실행해주는 기능입니다. 주로 API 호출, 데이터 유효성 검사 등 특정 데이터가 변경되자마자 어떠한 작업을 수행하려는 경우에 유용하게 사용됩니다. Vue3의 CompositonAPI에서는 감시자로 watch와 watchEffect를 사용할 수 있는데요, 이번 글에서는 watch()함수의 사용법을 하나씩 알아보도록 하겠습니다. 

 

📌 2. watch 사용법

watch(source, (newValue, oldValue) => {
   ........
});

1) 첫번째 인자: 감시하려는 소스
                         ref - ref를 사용하는 반응형 데이터
                         reactive - reactive의 getter함수를 사용하는 반응형 객체의 속성
                         다중 소스 

2) 두번째 인자: 콜백함수로 감시하려는 소스가 변경될 때마다 실행
                         ① 콜백함수의 첫번째 인자: 변경 이후의 값
                         ② 콜백함수의 두번째 인자: 변경 이전의 값
                         ③ 콜백함수의 세번째 인자(선택사항)
                             : onInvalidate, 필요할 때 작업을 정리하거나 취소하는 등 부작용을 관리

 

📌 2. watch 사용 예시 

💡   ref 사용법 

<script setup>
import { ref, watch } from 'vue';

const counter = ref(0);
const smile = ref('😀');

watch(counter, (newCount, oldCount) => {
  console.log(`Counter: ${counter.value} (from ${oldCount} to ${newCount} ${smile.value})`);
});
</script>

<template>
  <div>
    <h1>Counter: {{ counter }}</h1>
    <button @click="counter++">Increment</button>
  </div>
</template>

ref는 반응성을 가진 상태 데이터를 생성할때, 반응 객체 데이터를 래핑하기때문에 실제 데이터에 접근하려면 '.value'속성을 사용해야합니다. 위 예시에서 counter와 smile에 접근할 때 '.value' 속성을 사용하였습니다.
🚨그러나, watch()함수의 두번째인자인 콜백함수에서의 인자들은 객체가 아닌 'ref.value'에 해당하는 값입니다.그래서 감시하려는 대상이 ref()를 이용해 만든 반응성을 가진 데이터 객체라고 할지라도 newCount, oldCount같은 콜백함수의 인자들은 '.value'속성을 사용하지 않는다는 점을 꼭 기억해야합니다. 

 

💡   reactive 사용법 

<script setup>
import { reactive, watch } from 'vue';

const cart = reactive({
  item: 'Pencil',
  count: 0
});

watch(() => cart.count, (newCount, oldCount) => {
  console.log(`Total Item: ${cart.count} (from ${oldCount} to ${newCount})`);
});

</script>

<template>
  <div>
    <p>Item: {{ cart.item }}</p>
    <p>Count: {{ cart.count }}</p>
    <button @click="cart.count++">Increase</button>
  </div>
</template>

 ❓  cart의 count값이 변경될 때마다 감시하고 싶다면, watch의 첫번째 인자로 뭘 넣으면 될까요?

reactive로 만든 반응형 객체의 특정 속성의 변경 사항을 감시하려면, watch함수의 첫번째 인자로 getter함수를 사용하면 됩니다. getter 함수를 사용하면 관심 있는 속성의 변경 사항만 감지해서 원하는 콜백함수를 실행할 수 있습니다.

위 예제에서 Vue는 cart.count의 변경 사항을 추적하는데요. getter 함수'() => cart.count'가 watch함수의 첫번째 인자로 설정된 것 보이시나요? 이 설정을 통해 Vue는  cart라는 반응형 객체의 count만을 정확히 감시할 수 있습니다😉

watch가 cart.count변경 사항을 감지하면, count의 변경 전 값과 변경 후 값을 콜백함수에 직접 전달해주줍니다. countreactive 객체의 속성이므로 관련된 .value가 없습니다. 그래서 cart.count는 watch함수 안에서 직접 접근이 가능합니다. oldCount와 newCount 또한 콜백에 집접 전달되는 값이므로 바로 접근이 가능합니다.

 

💡   다중 감시자 사용법 

❓  여러개의 값을 감시하다가 하나의 핸들러를 실행하고 싶을 땐 어떻게 할까요?
이럴때는 다중 감시자를 사용합니다. watch()함수의 인자로는 여러개의 값을 줄때는 배열로 감싸서 보내줍니다.

<script setup>
import { ref, reactive, watch } from 'vue';

const temperature = ref(25);
const humidity = ref(50);
const finedust = reactive({
  quality: 'Good'
});

watch(
  [temperature, humidity, () => finedust.quality],
  ([newTemperature, newHumidity, newFinedust], [oldTemperature, oldHumidity, oldFinedust]) => {
    console.log(`Temperature: ${temperature.value} (from ${oldTemperature}°C to ${newTemperature}°C)`);
    console.log(`Humidity: ${humidity.value} (from ${oldHumidity}% to ${newHumidity}%)`);
    console.log(`finedust: ${finedust.quality} (from ${oldFinedust} to ${newFinedust})`);
  }
);


function showYesterday(temp, humid, quality) {
  temperature.value += temp;
  humidity.value += humid;
  finedust.quality = quality;
}
</script>

<template>
  <div>
    <h1>Weather</h1>
    <p>Temperature: {{ temperature }}°C</p>
    <p>Humidity: {{ humidity }}%</p>
    <p> Quality: {{ finedust.quality }}</p>
    <button @click="showYesterday(3, 5, 'Bad')">Show Yesterday</button>
  </div>
</template>

위 예시에서는 세가지 소스를 모니터링 하였는데요. 온도(temperature)와 습도(humidity)를 나타내는 ref값과 미세먼지를 나타내는 reactive값입니다. watch()함수의 첫번째 인자에는 소스값을 배열로 묶어서 넣었습니다. reactive 반응성 객체는 getter함수(() => finedust.quality)를 이용해서 원하는 값을 특정하였습니다. 콜백함수의 인자에는 각 소스의 변경전 값들과 변경 후 값들을 배열로 묶어서 넣었습니다. watch()함수에서는 배열로 묶기만 해주면 여러개의 값도 감시해서 원하는 코드를 실행시킬 수 있습니다.