ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Vue] Computed and Watch
    Javascript/Vue.js 2019. 8. 26. 17:25
    반응형

    computed

     Vue 인스턴스에는 computed 라는 속성이 있습니다. 이 속성은 평소에는 자신의 계산된 값을 캐싱하고 있습니다. 자신이 의존하고 있는 속성이 변경되지 않는 한, 함수를 실행하지 않습니다. 만약 자신이 의존하고 있는 속성이 변경된다면 함수가 호출되어 자신이 가지고 있는 값을 갱신합니다.

     

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
    <div id="app">
      <button v-on:click="counter++">Increase</button>
      <button v-on:click="counter--">Decrease</button>
      <button v-on:click="secondCounter++">Increase Second</button>
      <p>Counter : {{ counter }} | {{ secondCounter }}</p>
      <p>Result : {{ result() }} | {{ output }}</p>
    </div>
    
    <script>
        new Vue({
            el: '#app',
            data: {
                counter: 0,
                secondCounter: 0
            },
            computed: {
                output: function() {
                    console.log('Computed');
                    return this.counter > 5 ? 'Greater 5' : 'Smaller than 5';
                }
            },
            methods: {
                result: function() {
                    console.log('Method');
                    return this.counter > 5 ? 'Greater 5' : 'Smaller than 5';
                }
            }
        });
    </script>

     위 코드를 보면 html 코드에 삽입된 Interpolation 으로 인해 최초 렌더링이 될 때, computed의 output 메서드와 methods의 result 메서드가 호출되어 콘솔 출력이 된 것을 볼 수 있습니다. 현재의 코드에서 Increase 나 Decrease 버튼을 누르면 counter 값이 변경되어 DOM 상에서 전체적으로 렌더링이 일어납니다.

     

    여기서 computed의 output 속성은 counter 에 의존적이므로 함수가 호출되어 "Computed" 메시지를 콘솔에 출력합니다.

    methods의 result() 함수는 DOM이 렌더링되는 과정에서 마지막 <p> 태그의 {{ result() }} 코드로 인해 함수가 호출되어 "Method" 메시지를 콘솔에 출력합니다.

     

     

     여기서 IncreaseSecond 버튼을 누르면 어떻게 될까요??

     IncreaseSecond 버튼은 클릭 시, secondCounter 값을 변경 시키므로 렌더링이 되어 마찬가지로 methods의 result() 함수가 호출될 것입니다. 하지만, secondCounter 속성은 computed의 output 속성과는 아무런 의존관계가 없으므로 호출되지 않습니다.

     콘솔의 마지막 출력을 보면 Increase Second 버튼을 누른 결과, methods의 result() 함수만 호출된 것을 확인할 수 있습니다.

     이처럼 computed 속성은 평소에는 자신의 값을 캐싱시켜두었다가 필요한 시점에만 계산하여 불필요한 호출을 줄일 수 있습니다.

     


    watch

     watch 도 속성 값의 변경을 감시한다는 점에서 computed 와 유사한 기능을 가지고 있습니다. 둘의 차이점은 사용의 용도입니다. computed는 의존하는 속성에 변화가 있을 때, 동기적으로 호출되어 함수를 수행한 후에 값을 반환합니다.

     

     이와 반대로 watch는 비동기적으로 처리를 하거나 컴포넌트의 외부 동작을 처리하는데 적합합니다. watch에 선언된 함수는 첫 번째 인자에 변경된 값이 인자로 전달되고, 두 번째 인자에는 변경 전의 값이 인자로 전달됩니다. 라고 하면서 사실 저는 이해가 잘 되지 않았습니다. 하는 역할은 비슷한데 단순히 "동기냐, 비동기냐, 아니면 처리량에 따라서 사용해야한다." 라는 기준이 저에게 와닿지가 않았습니다. 그래서 찾아본 결과 ,아래의 링크를 통해서 조금 더 쉽게 정리가 되었습니다.

    https://skout90.github.io/2018/01/24/Vue/1.1.Computed-VS-Watch/

     

    위의 블로그를 통해 알게된 추가적인 정보는 아래와 같습니다.

    • watch는 템플릿 표현식 없이도 값의 변화를 관찰할 수 있습니다.
    • computed는 DOM에서 템플릿 표현식을 통해 참조되지 않으면 계산되지 않습니다.

     이를 바탕으로 실제로 그러한지 예제 코드를 작성해보았습니다.

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
    <div id="app">
      <button v-on:click="add">Increase</button>
      <button v-on:click="sub">Decrease</button>
      <p>Counter : {{ counter }}</p>
    </div>
    
    <script>
        new Vue({
            el: '#app',
            data: {
                counter: 0
            },
            computed: {
                output: function() {
                    console.log('Computed');
                    return this.counter;
                }
            },
            methods: {
                add: function() {
                    this.counter++;
                },
                sub: function() {
                    this.counter--;
                }
            },
            watch: {
                counter: function(newVal, oldVal) {
                    console.log('newVal : ' + newVal);
                    console.log('oldVal : ' + oldVal);
                    console.log(this.counter);
                    return this.counter;
                }
            }
        });
    </script>

     위에서 보이는바와 같이 counter가 변경되어도 computed는 템플릿 표현식이 존재하지 않으므로 호출되지 않습니다. 반면, watch는 값이 바뀔 때 호출되는 결과를 볼 수 있습니다.

     


    참고 자료

    https://www.udemy.com/vuejs-2-the-complete-guide/

    https://skout90.github.io/2018/01/24/Vue/1.1.Computed-VS-Watch/

    반응형

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

    [Vue] Directive hook  (0) 2019.09.13
    [Vue] Lifecycle  (0) 2019.09.01
    [Vue.js] DOM event 핸들링 방법  (0) 2019.08.20
    Vue.js 와 DOM의 상호작용 방법  (0) 2019.08.18

    댓글

Designed by Tistory.