uxtry

vue: Watch와 WatchEffect 본문

Vue.js 3 주요 문법 (vue:)

vue: Watch와 WatchEffect

uxtry 2024. 11. 26. 11:14

vue watch 데이터의 변화를 감지 with chatGPT

Vue의 watchwatchEffectComposition API 에서 반응형 데이터의 변화를 감지하고 특정 작업을 수행하기 위해 사용됩니다.

두 기능은 비슷해 보이지만, 사용 목적과 동작방식이 다릅니다.

 

1. watch

watch특정 데이터(반응형 상태)의 변화를 감지하고 그에 따라 작업을 실행합니다.

 

특징:

  • 특정 데이터를 명시적으로 감시합니다.
  • 초기 실행 없이, 데이터가 변경될 때만 실행됩니다.
  • 비동기 작업에 유용합니다.

사용 예제

<template>
<div>
	<input v-model="text" placeholder="텍스트를 입력하세요"/>
    <p>텍스트: {{ text }}</p>
</div>
</template>

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

export default{
	setup() {
    	const text = ref(''); //반응형 데이터
        
        watch(text, (newValue, oldValue) => {
        	console.log(`변경됨: ${oldValue} -> ${newValue}`);
        });
        
        return { text };
    },
};
</script>

작동 방식:

  • 사용자가 text를 변경할 때만 watch 콜백이 실행됩니다.
  • newValue: 변경된값, oldValue: 변경되기 전의 값.

복수 데이터 감시

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

export default {
  setup() {
    const count = ref(0);
    const name = ref('Vue');

    watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
      console.log(`count: ${oldCount} -> ${newCount}, name: ${oldName} -> ${newName}`);
    });

    return { count, name };
  },
};
</script>

 

비동기 작업 예제

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

export default {
	setup() {
    	const searchTerm = ref('');
        
        watch(searchTerm, async (newTerm) => {
        	if(newTerm){
            	const response = await fetch(`https://api.example.com/search?q=${newTerm}`);
                const results = await respons.json();
            	console.log('검색결과:', results);
            }
        });
        
        return { searchTerm }
    },
};
</script>

 

watch의 옵션

  • immediate: 감시 초기 시점에 즉시 콜백 실행.
  • deep: 객체 내부 속성 변경까지 감지.
watch(
	date,
    (newVlaue, oldVlaue) => {
    	console.log('데이터 변경: ', newValue);
    },
    { immediate: true, deep: true }
);

 

2. watchEffect

watchEffect반응형 상태와 관련된 모든 값의 변화를 자동으로 추적하여 작업을 실행합니다.

 

특징:

  • 감시 대상을 명시하지 않아도 됩니다.
  • 선언된 반응형 상태가 사용되기만 하면 자동으로 감지합니다.
  • 초기 실행 시  한 번 실행됩니다.

사용 예제

<template>
  <div>
    <input v-model="text" placeholder="텍스트를 입력하세요" />
    <p>텍스트: {{ text }}</p>
  </div>
</template>

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

export default {
  setup() {
    const text = ref('');

    watchEffect(() => {
      console.log(`텍스트 값: ${text.value}`);
    });

    return { text };
  },
};
</script>

작동 방식:

  • text.value가 변경되면 자동으로 watchEffect가 실행됩니다.
  • 초기화 시점에 한 번 실행됩니다.

의존성 추적

watchEffect는 내부에서 사용하는 반응형 데이터를 자동으로 추적합니다. 추가적으로 특정 데이터를 명시할 필요가 없습니다.

<script>
import { ref, watchEffect } form ''vue;

export dafault{
	setup(){
    	const count = ref(0);
        const doubled = ref(0);
        
        watchEffect(() => {
        	doubled.value = count.value * 2 //count가 변경되면 자동 실행
            console.log(`count: ${count.value}, doubled: ${doubled.value}`)
        });
        
        return {count, doubled};
    },
};
</script>

 

3. wartch VS watchEffect

특성 watch watchEffect
감시 대상 특정 데이터(명시적으로 지정) 사용된 모든 반응형 데이터
초기 실행 기본적으로 실행되지 않음
(immediate로 설정가능)
항상 초기 실행됨
비동기 작업 바동기 로직에 적합 비동기 로직 사용 시 주의 필요
옵션 지원  immediate, deep 등 다양한 옵션 지원 옵션 지원 없음
사용 사례 특정 데이터의 변화를 감지하고 특정 작업을 수행할때 여러 상태를 자동 추적하거나 간단한 로직을 구현할 때

 

4. 결합 예제

<template>
  <div>
    <h1>검색 기능</h1>
    <input v-model="searchTerm" placeholder="검색어를 입력하세요" />

    <p>
      <strong>현재 검색어:</strong> {{ searchTerm || '없음' }}
    </p>
    <p>
      <strong>로딩 상태:</strong> {{ isLoading ? '로딩 중...' : '완료' }}
    </p>
    <p>
      <strong>검색 결과 개수:</strong> {{ searchResults.length }}
    </p>

    <ul>
      <li v-for="result in searchResults" :key="result.id">{{ result.name }}</li>
    </ul>
  </div>
</template>

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

export default {
  setup() {
    const searchTerm = ref('');
    const searchResults = ref([]);
    const isLoading = ref(false);

    // 1. watch: searchTerm이 변경될 때 API 호출
    watch(searchTerm, async (newTerm) => {
      if (!newTerm) {
        searchResults.value = []; // 검색어가 없을 때 결과 초기화
        return;
      }

      isLoading.value = true; // 로딩 상태 시작
      try {
        const response = await fakeApiSearch(newTerm);
        searchResults.value = response; // API 결과 저장
      } catch (error) {
        console.error('API 호출 실패:', error);
      } finally {
        isLoading.value = false; // 로딩 상태 종료
      }
    });

    // 2. watchEffect: 상태 추적 및 UI 표시용 데이터 설정
    watchEffect(() => {
      // 이 부분은 상태 추적의 역할을 하며, 결과는 UI에서 직접 표시됩니다.
    });

    // 더미 API 함수
    const fakeApiSearch = async (term) => {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve([
            { id: 1, name: `${term} 결과 1` },
            { id: 2, name: `${term} 결과 2` },
            { id: 3, name: `${term} 결과 3` },
          ]);
        }, 1000); // 1초 대기 후 결과 반환
      });
    };

    return {
      searchTerm,
      searchResults,
      isLoading,
    };
  },
};
</script>

★ Vue SFC Playground 코드 실행 →

  • 검색어 표시: 현재 검색어를 텍스트로 표시합니다. 입력이 없을때는 "없음"으로 표시됩니다.
  • 로딩 상태 표시: 검색어 변경 시 API호출 상태에 따라 "로딩 중..." 또는 "완료를 표시합니다."
  • 검색결과 개수: 검색결과의 개수를 텍스트로 표시하며, searchResult 배열의 길이를 참조합니다.
  • 검색결과 표시: 검색결과 목록을 <ul>로 출력, 각 결과의 name속성을 표시합니다.

5. 요약

  • watch:  특정 데이터 변경을 감지하여 실행할 때 사용.(명시적)
  • watchEffect: 모든 반응형 상태의 변화를 자동 추적하고 실행. (자동 추적)
  • Vue 3의 Composition API에서 반응형 상태를 효과적으로 관리할 수 있는 도구로, 상황에 맞게 사용하면 효율적인 관리가 가능합니다.

'Vue.js 3 주요 문법 (vue:)' 카테고리의 다른 글

vue: Single File Component  (0) 2024.12.19
vue: 컴포넌트 기초  (1) 2024.11.29
vue: 양방향 바인딩(v-model)  (0) 2024.11.22
vue: 이벤트 처리  (0) 2024.11.21
vue: Drective  (0) 2024.11.20