본문으로 바로가기

Computed와 Watch

category JavaScript/Vue.js 2021. 7. 15. 16:42

Computed와 Watch는 둘 다 Vue 인스턴스 내의 정의된 데이터 값에 변경이 일어나고 있는지를 감시하고, 변경될 때마다 정의된 함수가 실행됨. 데이터의 값이 변경되었는 지를 계속 감시한다는 측면에서 Computed와 Watch는 매우 비슷해 보이지만, 사용되는 용도에는 분명 차이가 있다.

 

Computed

- Computed는 Vue 인스턴스 내에 정의된 데이터 값과 연관된 또 하나의 데이터를 정의해서 사용할 수 있도록 해줌

<template>
  <h1>Full Name: {{ fullName }}</h1>
</template>
<script>
  export default {
    data() {
      return {
        firstName: 'Gildong',
        lastName: 'Hong',
      }
    },
    computed: {
      fullName() {
        return this.firstName + ' ' + this.lastName
      },
    },
  }
</script>

 - computed 내에 fullName이 정의되어 있고, firstName과 lastName을 합쳐서 반환해주는 함수로 정의되어 있다.

 - 여기서 함수명인 fullName은 함수이자 동시에 Vue 인스턴스의 데이터 키 값이다. firstName, lastName을 Vue 인스턴스의 데이터 값으로 사용하는 것과 동일한 데이터 값으로 선언되는 것이다.

 - computed는 데이터 값에 변경이 일어나는 지를 감시한다고 했습니다. computed로 정의하면 fullName 함수가 실행되어 firstName과 lastName을 합한 값이 할당 됩니다. 그리고 firstName 혹은 lastName 값 중 하나라도 변경이 일어나면 fullName 함수가 자동으로 실행되고, fullName 값이 갱신 됨

 

정리해보면 computed에 정의된 fullName은 함수이자 동시에 Vue 인스턴의 데이터입니다.
computed에 정의해서 사용하면 화면 내 여러 곳에서 fullName을 사용하더라도 이에 대한 연산은 한 번 밖에 일어나지 않습니다.
문자열 표현식인 이중 중괄호 안에서 2개의 데이터 값을 합하는 연산과 함수로 구현된 연산이 화면에 보이는 수 만큼 호출되어 연산을 다시 하는 것과 큰 차이가 있습니다.
또한, 함수를 이용해서 fullName을 계산하는 경우는 firstName 혹은 lastName에 변경이 일어났을 때를 감지할 수 없습니다.

 

Watch

 - Watch 역시 computed처럼 Vue 인스턴스에 정의된 데이터 값이 변경이 일어나는지를 감시하고, 변경이 일어나면 지정된 함수를 실행 시킬 수 있다.

 - 하지만 computed의 경우는 기존에 정의된 데이터 값을 기반으로 새로운 데이터 값을 활용하기 위해서 사용이 된다면 watch는 watch에 정의된 데이터 값 하나만을 감시하기 위한 용도로 사용된다.

 - 또한 computed와 다르게 실제 데이터 변경이 일어나기 전까지는 실행되지 않는다. 즉, 초기에 지정된 값인 firstName과 lastName에 값이 있음에도 불구하고 fullName은 여전히 아무런 값도 항당되지 않는다.

 - firstName과 lastName의 초기에 할당된 값이 반드시 변경이 일어나야만 watch가 실행된다.

<template>
  <div>
    <h1>Full Name : {{ fullName }}</h1>
    <button type="button" @click="changeName">변경</button>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        firstName: 'Gildong',
        lastName: 'Hong',
        fullName: '',
      }
    },
    watch: {
      firstName() {
        this.fullName = this.firstName + ' ' + this.lastName
      },
      lastName() {
        this.fullName = this.firstName + ' ' + this.lastName
      },
    },
    methods: {
      changeName() {
        this.lastName = 'Kim'
      },
    },
  }
</script>

 - Vue 컴포넌트를 실행하면 처음에는 Full Name이 보이지 않지만, 버튼을 클릭하면 lastName 변경으로 인해 watch가 실행되고, firstName 함수를 통해 fullName이 갱신됨

 

 

Computed는 정의된 데이터 값을 바탕으로 새로운 데이터 값을 생성하고, 새로운 데이터 값에서 참조하고 있는 기존 데이터 값의 변경을 감지합니다. 그리고 참조하고 있는 데이터 값의 변경과 상관없이 최초에 computed에 정의된 데이터 함수를 실행합니다.

Watch는 초기에 할당된 값에서 변경이 일어나야 watch에 정의한 함수를 실행한다.

 

 

일하면서 생긴일

 - arr = [] 이라는 변수를 data에 선언을 했다고 가정한다.

 - arr[1] = 'hello'와 같이 methods에서 값을 넣는다면 Vue에서 해당 데이터가 변경되었다고 감지하지 못할 수도 있다.

   ( Computed나 Watch에서도 데이터가 변경되었다고 감지를 하지 못하니 동작하지 않았음.. )

 - push나 pop 함수를 사용하면 감지를 한다고 한다.

 - 하지만 원하는 위치의 인덱스로 넣고 싶다면 let tmp = arr.slice(0, arr.length) 처럼 배열을 복사한 뒤

 - 데이터를 tmp에 넣고 arr를 초기화 후(쓸모없는 데이터 방지를 위해)  tmp를 arr에 넣어주면 된다.

 - 하지만 작업 과정이 추가되는 것이므로 다른 좋은 방법이 있다면 다른 방법을 사용하는 것을 추천한다.

반응형

'JavaScript > Vue.js' 카테고리의 다른 글

컴포넌트 심화 학습 (Slot)  (0) 2021.07.16
컴포넌트 심화 학습(Props, $refs, $emit)  (2) 2021.07.16
이벤트 처리 (v-on)  (0) 2021.07.15
랜더링(v-for, v-if, v-show)  (0) 2021.07.15
데이터 바인딩(Data Binding)  (0) 2021.07.15