본문 바로가기
vue.js/기술

[vue] watch / computed / watcheffect

by 냉면돈가스 2022. 1. 19.

위 키워드들은 데이터 값이 바뀔때마다 감시자 역할을 해주는 메소드들임

https://v3-docs.vuejs-korea.org/guide/essentials/watchers.html

 

감시자 | Vue.js

 

v3-docs.vuejs-korea.org


watch

 

# watch 간단하게 사용하기

<template>
  <div>
    <input type="text" v-model="a" />
  </div>
</template>

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

const a = ref(0);

watch(a, (v) => {
  console.log(v.value);
});
</script>

 

 

 

# 객체 감지하기

<template>
  <div>
    <input type="text" v-model="b.count" />
  </div>
</template>

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

const b = reactive({ count: 0 });

watch(b, (v) => {
  console.log(v); // 작동잘됨
});
watch(b.count, (v) => {
  console.log(v); // 작동안됨
});
</script>

 

​객체를 감지할때는 객체안의 요소만 감지할수는 없다.

첫번째 나열된 watch처럼 b 객체 전체를 감지해야한다.

이로 인해 특정한 데이터만 추출하여 감시하는 것이 아닌,

불필요한 데이터 전체를 감시하게 되어버리는데

이는 watch 문장을 조금 바꾸어주면 해결됨

<template>
  <div>
    <input type="text" v-model="b.count" />
  </div>
</template>

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

const b = reactive({ count: 0 });

watch(b, (v) => {
  console.log(v); // 작동잘됨
});
watch(b.count, (v) => {
  console.log(v); // 작동안됨
});
watch(
  () => b.count,
  (v) => {
    console.log(v); // b.count의 변경만 감지됨
  }
);
</script>

 

 

# 기타 옵션들

 

## deep

 

deep은 배열이나 객체등 깊게 감시해주도록 나온것인데,

위에 나온대로 watch 문장을 바꾸어주니 해결됐음

vue2때는 유용하게 사용했다. (작성자 기준)

https://v3-docs.vuejs-korea.org/guide/essentials/watchers.html#deep-watchers

 

감시자 | Vue.js

 

v3-docs.vuejs-korea.org

 

## immediate

 

watch는 컴포넌트가 created 될 때의 데이터 변경까지 감시해주진않는다.

immediate를 사용하면 감시 가능

https://v3-docs.vuejs-korea.org/guide/essentials/watchers.html#eager-watchers

 

감시자 | Vue.js

 

v3-docs.vuejs-korea.org

 

## flush

 

watch는 기본적으론 DOM의 업데이트 시기를 계산하여 감시하진 않음

이 말인 즉슨, 감시당하는 값을 A라 칭하고

A를 변경 후, A에 의존적인 DOM이 변경되고있을때 watch를 먼저 실행해버려 

DOM이 변경완료된 후가 아닌 DOM 변경이전을 감시한단 소리

 

이 타이밍을 제어하고 싶다면 flush를 사용한다.

https://v3-docs.vuejs-korea.org/guide/essentials/watchers.html#callback-flush-timing

 

감시자 | Vue.js

 

v3-docs.vuejs-korea.org

 

## watch 종료하기

 

watch를 잘 사용하다가도 

어느시점부터 사용하고 싶지 않을 수 있음

watch특성상 여러번 호출이되기도하니 해제하면 좋을듯

 

아래 소스처럼 3초뒤에 watch를 해제할수도있고,

watch 실행문장안에 자신을 호출하게 하여 단 한번만 실행시킬 수도 있음

1-1. watch를 변수에 할당시킴
const set = watch(() => a.value.count, (newValue, oldValue) => {
  console.log('value1이 변경되었습니다:', newValue);
}

1-2. 3초뒤에 watch 해제
setTimeout(()=>{
  set();
},3000)

2 watch를 한번만 실행
const set = watch(() => a.value.count, (newValue, oldValue) => {
  console.log('value1이 변경되었습니다:', newValue);
  set()
}

 


watchEffect

 

watchEffect는 단일 값, 혹은 하나의 객체 값만 감지하는것과 달리

한 메소드로 여러 데이터를 감지할 수 있다.

편해서 쓰는 것

 

# 사용법

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

let a = ref(5);
let b = ref(3);
let c = ref(0);
watchEffect(() => {
  c.value = b.value+a.value;
});
</script>

<template>
<div>
  <div>
    a = <input type="number" v-model="a" /> {{a}}
  </div>
  <div>
    b = <input type="number" v-model="b" /> {{b}}
  </div>
  <div>
  c = {{c}}
  </div>
</div>
</template>

 

watchEffect 안에 들어가 있는 데이터를 모두 감시하여

a,b 두 데이터 중 하나라도 변경되면 실행해준다.


computed

 

firstName과 lastName을 조합하여 fullName을 만드려고한다.

 

## watch와 coumputed의 비교

<template>
  <div>
    <input type="text" v-model="firstName" />
    <input type="text" v-model="lastName" />
    {{ fullName }}
  </div>
</template>

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

const firstName = ref("세");
const lastName = ref("종");
const fullName = ref("세종");

watch(firstName, (v) => {
  fullName.value = v + lastName.value;
});
watch(lastName, (v) => {
  fullName.value = firstName.value + v;
});
</script>

 

firstName과 lastName 각각 watch 문을 작성해주어야해서 번거롭다.

computed로 변경시 특정 값들의 변화를 이용하여 데이터를 간편하게 생성 할 수 있다.

<template>
  <div>
    <input type="text" v-model="firstName" />
    <input type="text" v-model="lastName" />
    {{ fullName }}
  </div>
</template>

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

const firstName = ref("세");
const lastName = ref("종");
// const fullName = ref("세종");
const fullName = computed(() => firstName.value + lastName.value);
// watch(firstName, (v) => {
//   fullName.value = v + lastName.value;
// });
// watch(lastName, (v) => {
//   fullName.value = firstName.value + v;
// });
</script>

 

 

## 메소드를 이용하는 방법과 비교

 

1. 메소드를 이용하여 fullName을 생성

2. computed를 이용하여 fullName을 생성

fullName을 template에 바로 뿌려준다고 가정할 시,

 

computed 안에 이용된 데이터가 변경될때마다 메소드를 실행하여 결과 데이터(fullName)가 갱신됨

computed는 종속 대상이 변경될 때만 computed를 수행함.

 

메소드는 종속된 개념이 딱히 없음

fullName을 만들어내는 메소드를 tamplate에서 뿌려주다보니 렌더링을 할때마다 (update 라이프 사이클이 수행될 때 마다) 실행해버려

불필요한 노동이 추가된다.

 

 

'vue.js > 기술' 카테고리의 다른 글

[vue] v-slot  (1) 2022.01.19
[vue] props  (0) 2022.01.19
[vue] vue 키 이벤트  (0) 2022.01.19
[vue] vue HTML 데이터 바인딩 (sanitize-html)  (0) 2022.01.19
[vue] vue 프로젝트 생성  (0) 2022.01.18

댓글