computed

vue instance가 가진 options 중 하나 

computed 객체에 정의한 함수를 페이지가 최초 렌더링 시 호출하여 계산

계산 결과가 변하기 전까지 그 저장된 값을 그대로 사용한다.

 

  <div id="app">
    <h1>data_01 : {{ number1 }}</h1>
    <h1>data_02 : {{ number2 }}</h1>
    <hr>
    <h1>add_method : {{ add_method() }}</h1>
    <h1>add_method : {{ add_method() }}</h1>
    <h1>add_method : {{ add_method() }}</h1>
    <hr>
    <h1>add_computed : {{ add_computed }}</h1>
    <h1>add_computed : {{ add_computed }}</h1>
    <h1>add_computed : {{ add_computed }}</h1>
    <hr>
    <button v-on:click="dataChange">Change Data</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number1: 100,
        number2: 100
      },
      computed: {
        add_computed: function () {
          console.log('computed 실행됨!')
          return this.number1 + this.number2
        }
      },
      methods: {
        add_method: function () {
          console.log('method 실행됨!')
          return this.number1 + this.number2
        },
        dataChange: function () {
          this.number1 = 200
          this.number2 = 300
        }
      }
    })
  </script>

메서드는 method()으로 실행하고 computed는 괄호 없이 실행했다.

세번씩 작성해서 실행했지만, method는 계속해서 3번 실행되는 반면, computed는 값이 변화하지 않았기 때문에 1번만 실행된다.

 

 

method, computed 비교

method

- 호출 될 때마다 함수를 실행

- 같은 결과여도 매번 새롭게 실행하여 계산한다.

- 사용 시 ()가 붙는다.

 

computed

- 함수의 종속대상 변화에 따라 계산 여부 결정된다.

- 종속 대상(결과에 영향을 미치는 값)이 변하지 않으면 항상 저장된 값을 반환

- 호출하는 것이 아니라, 계산된 값으로서 사용되기 때문에 ()가 붙지 않는다.

 

 

 

 

watch

 <div id="app">
    <h3>Increase number</h3>
    <p>{{ number }}</p>
    <button @click="number++">+</button>
    <hr>

    <h3>Change name</h3>
    <p>{{ name }}</p>
    <input type="text" v-model="name">
    <hr>

    <h3>push myObj</h3>
    <p>{{ myObj }}</p>
    <button @click="itemChange">change Item</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
        name: '',
        myObj: {completed: true}
      },
      methods: {
        nameChange: function () {
          console.log('name is changed')
        },

        itemChange: function () {
          this.myObj.completed = !this.myObj.completed
        }
      },
      watch: {
        number: function (val, oldVal) {
          console.log(val, oldVal)
        },

        name: {
          handler: 'nameChange'
        },

        myObj: {
          handler: function (val) {
            console.log(val)
          },
          deep: true
        },
      }
    })
  </script>

watch는 특정 데이터의 변화를 감지한다.

 

 watch: {
        number: function (val, oldVal) {
          console.log(val, oldVal)
        },

watch 객체를 정의하여 감시할 대상 data를 지정한다. data가 변할시에 실행할 함수를 정의한다.

data가 변하면 함수가 실행된다. 함수의 첫번째 인자는 변동 후 data, 두번째 인자는 변동 전 data이다.

number를 감시하며, number가 변하면 변동후 data, 변동전 data를 출력하는 함수를 실행한다.

 

 

  watch: {
    name: {
      handler: 'nameChange'
    }
  }

실햄 함수를 vue method로 대체 가능하다.

감시 대상 data의 이름으로 객체를 생성하고 실행하고자 하는 method를 handler에 문자열 형태로 할당한다.

name이 변경되면 nameChange 메서드가 실행된다.

 

 

  watch: {
    myObj: {
      handler: function (val) {
        console.log(val)
      },
      deep: true
    },
  }

array, object 같이 [], {} 안에 있는 요소의 변경을 감지하기 위해서는 deep : true 속성을 추가하면 된다.

 

 

 

  <div id="app">
    <h3>Increase number</h3>
    <p>{{ number }}</p>
    <button @click="number++">+</button>
    <hr>

    <h3>Change name</h3>
    <p>{{ name }}</p>
    <input type="text" v-model="name">
    <hr>

    <h3>push myObj</h3>
    <p>{{ myObj }}</p>
    <button @click="itemChange">change Item</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
        name: '',
        myObj: {completed: true}
      },
      methods: {
        nameChange: function () {
          console.log('name is changed')
        },

        itemChange: function () {
          this.myObj.completed = !this.myObj.completed
        }
      },
      watch: {
        number: function (val, oldVal) {
          console.log(val, oldVal)
        },

        name: {
          handler: 'nameChange'
        },

        myObj: {
          handler: function (val) {
            console.log(val)
          },
          deep: true
        },
      }
    })
  </script>

 

 

 

computed, watch 비교

데이터 변경을 관찰하고 이에 반응하는 일반적인 방법은 watch 속성이다. 그러나 명령형 watch 콜백보다 computed 속성을 쓰는 것이 더 나은 경우도 많다. computed로 구현가능한 것이라면 watch가 아니라 computed로 구현하는것이 대게의 경우 옳다.

<div id="demo">{{ fullName }}</div>
 
const vm = Vue.createApp({
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
      fullName: 'Foo Bar'
    }
  },
  watch: {
    firstName(val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName(val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
}).mount('#demo')

위 코드는 watch를 사용한 명령형이고 코드가 반복된다.

 

 

 

 

const vm = Vue.createApp({
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar'
    }
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  }
}).mount('#demo')

computed를 이용한 코드가 더 간편한 경우이다.

 

 

 

filters

<body>
  <div id="app">
    <p>{{ numbers }}</p>
    <p>{{ numbers | getOddNums }}</p>
    <p>{{ numbers | getOddNums | getUnderTenNums }}</p>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
      },
      filters: {
        getOddNums: function (nums) {
          const oddNums = nums.filter((num) => {
            return num % 2
          })
          return oddNums
        },
        
        getUnderTenNums: function (nums) {
          const underTen = nums.filter((num) => {
            return num < 10
          })
          return underTen
        }
      }
    })
  </script>

텍스트 형식화를 적용할 수 있는 필터

interpolation 혹은 v-bind를 이용할 때 사용 가능하다.

필터는 자바스크립트 표현식 마지막에 | 파이프와 함께 추가되어야 한다.

chaining하여 이어서 사용할 수 있다.