-
[가이드] Computed와 Watch - 필수요소 | VueFront-end/Vue.js 2020. 8. 12. 13:10반응형
Computed Properties
템플릿 내 표현식은 매우 편리하지만 간단한 작업을 위한 것입니다. 템플릿에 논리를 너무 많이 넣으면 템플릿이 비대해지고 유지 관리가 어려워질 수 있습니다. 예를 들면 다음과 같습니다.
<div id="example"> {{ message.split('').reverse().join('') }} </div>
이 시점에서 템플릿은 더 이상 단순하고 선언적이지 않습니다. message를 거꾸로 표시한다는 것을 깨닫기 전에 잠시 살펴봐야 합니다. 이 문제는 반전된 메시지를 템플릿에 두 번 이상 포함하려는 경우 더 심각해집니다.
그렇기 때문에 복잡한 논리에 대해 computed 속성을 사용해야 합니다.
기본 예제
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> <script> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // computed getter reversedMessage: function () { // `this`는 VM 인스턴스를 가리 킵니다. return this.message.split('').reverse().join('') } } }) </script>
여기에서 computed 속성을 reversedMessage라고 선언했습니다 . 제공한 함수는 vm.reversedMessage 속성에 대한 getter 함수로 사용됩니다.
console.log(vm.reversedMessage) // => 'olleH' vm.message = 'Goodbye' console.log(vm.reversedMessage) // => 'eybdooG'
콘솔을 열고 예제 VM을 직접 재생할 수 있습니다. vm.reversedMessage 값은 항상 vm.message 값에 따라 달라집니다.
일반 속성처럼 템플릿에서 computed 속성에 데이터 바인딩할 수 있습니다. Vue는 vm.reversedMessage가 vm.message에 종속되므로 vm.message가 변경될 때 vm.reversedMessage에 종속된 모든 바인딩을 업데이트합니다. 그리고 가장 좋은 부분은 우리가 이러한 의존 관계를 선언적으로 만들어냈다는 것입니다. computed getter 함수에는 부작용이 없기 때문에 테스트하고 이해하기 쉽습니다.
Computed Caching vs Methods
다음 표현식에서 메서드를 호출하여 동일한 결과를 얻을 수 있음을 알 수 있습니다.
<p>Reversed message: "{{ reverseMessage() }}"</p> <script> // 컴포넌트 안에서 methods: { reverseMessage: function () { return this.message.split('').reverse().join('') } } </script>
computed 속성 대신 메서드와 동일한 함수를 정의 할 수 있습니다. 최종 결과에서, 두 접근법은 실제로 정확히 동일합니다. 그러나 차이점은 computed 속성이 반응 종속성을 기반으로 캐싱된다는 것 입니다. computed 속성은 반응 종속성 중 일부가 변경된 경우에만 재평가됩니다. 즉 message가 변경되지 않은 한 reversedMessage computed 속성에 대한 다중 액세스는 함수를 다시 실행할 필요없이 이전에 계산 된 결과를 즉시 반환합니다.
또한 Date.now()는 반응 종속성이 아니기 때문에 다음과 같은 computed 속성은 업데이트되지 않습니다.
computed: { now: function () { return Date.now() } }
이에 비해 메서드 호출은 리-렌더링이 발생할 때마다 항상 함수를 실행합니다.
캐싱이 필요한 이유는 무엇입니까? expensive한 computed 속성 A가 있다고 가정해 보십시오. 이 속성에는 거대한 array를 반복하고 많은 계산을 수행해야 합니다. 그러면 A에 의존하는 다른 computed 속성이 있을 수 있습니다. 캐싱이 없다면 A의 getter를 필요 이상으로 여러 번 실행하게 됩니다! 캐싱을 원하지 않는 경우에 대신 메소드를 사용합니다.
Computed vs Watched Property
Vue는 Vue 인스턴스의 데이터 변경 사항을 관찰하고 반응하는 일반적인 방법인 watch 속성을 제공합니다. 다른 데이터를 기반으로 변경해야 하는 데이터가 있는 경우, 특히 AngularJS에서 온 경우 watch를 과도하게 사용하려는 경우가 있습니다. 그러나 명령형 watch 콜백보다는 computed 속성을 사용하는 것이 더 나은 경우가 많습니다. 다음 예를 들어 보겠습니다.
<div id="demo">{{ fullName }}</div> <script> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } }) </script>
위의 코드는 필수적이며 반복적입니다. computed 속성 버전과 비교합니다.
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
Computed Setter
computed 속성은 기본적으로 getter 전용이지만 필요할 때 setter를 제공 할 수도 있습니다.
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
이제 vm.fullName = 'John Doe'를 실행하면 setter가 호출되고 그에 따라 vm.firstName 및 vm.lastName이 업데이트됩니다.
Watchers
computed 속성이 대부분의 경우에 더 적합하지만, 사용자 지정 watch가 필요할 때가 있습니다. 그렇기 때문에 Vue는 watch 옵션을 통해 데이터 변경에 보다 일반적인 방식으로 대응할 수 있습니다. 이 옵션은 데이터 변경에 대응하여 비동기식 또는 extensive한 작업을 수행할 때 가장 유용합니다.
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div> <!-- 이미 ajax 라이브러리와 범용 유틸리티 메서드의 풍부한 개발환경이 존재하기 때문에, Vue core는 이 라이브러리를 재창조하지 않음으로써 소규모로 유지할 수 있습니다. 이것은 또한 여러분에게 친숙한 것을 사용할 수 있는 자유를 줍니다. --> <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script> <script> var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // question이 변경 될 때마다이 기능이 실행됩니다. question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } }, created: function () { /* _.debounce는 lodash가 제공하는 기능으로서, 특히 비용이 많이 드는 작업을 얼마나 자주 실행할 수 있는지를 제한합니다. 이 경우 yesno.wtf/api에 액세스하는 빈도를 제한하고 사용자가 ajax 요청을 하기 전에 입력을 완전히 완료할 때까지 기다립니다. _.debounce 함수(및 그 사촌 _.throttle 함수)에 대해 자세히 알아보려면 https://lodash.com/docs#debounce를 방문하세요. */ this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) }, methods: { getAnswer: function () { if (this.question.indexOf('?') === -1) { this.answer = 'Questions usually contain a question mark. ;-)' return } this.answer = 'Thinking...' var vm = this axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) } } }) </script>
이 경우 watch 옵션을 사용하면 비동기 작업(API 액세스)을 수행하고, 해당 작업을 수행하는 빈도를 제한하며, 최종 답변을 얻을 때까지 중간 상태를 설정할 수 있습니다. computed 속성으로는 불가능합니다.
watch 옵션 외에도 명령형 vm. $ watch API 를 사용할 수도 있습니다 .
반응형'Front-end > Vue.js' 카테고리의 다른 글
[가이드] 리스트 렌더링 - 필수요소 | Vue (0) 2020.08.13 [가이드] 클래스와 스타일 바인딩 - 필수요소 | Vue (0) 2020.08.12 [가이드] 템플릿 문법 - 필수요소 | Vue (0) 2020.08.11 [가이드] Vue 인스턴스 - 필수요소 | Vue (0) 2020.08.11 [가이드] 시작하기 - Essentials | Vue (0) 2020.08.11