본문 바로가기
관리자

Programming-[Frontend]/Vue.js

Vue.js / 기초 / 3. 데이터 양방향 바인딩(v-model), computed, watch 속성

728x90
반응형

 

1. 데이터 양방향 바인딩을 통한 텍스트 미리보기 만들기(v-model)

 

input 입력창에 입력하는 텍스트 정보를 미리 볼 수 있는 요소를 만들어본다. v-model.html 파일로 만들어보자. 비슷하지만 코드를 여러 번 쳐보면서 익숙해지자!

 

<head> 태그에 cdn 코드 넣는 것 까먹지 말고...

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

v-model.html 파일

 

@keyup으로 바인딩

html에는 input 박스와 {{write}} data를 만들어 놓는다.

그리고 input창에 어떤 입력이 오면 추적을 하도록 @keyup 이벤트를 걸어놓는다(@ 는 v-on:의 단축어로 사용되니 기억하자!). 굳이 @keyup 이벤트에 textModifier라는 함수를 textModifier(event)와 같이 실행문에 파라미터를 넣는 방식으로 작성하지 않더라도, keyup 이벤트에서 알아서 파라미터를 추적하고, 실행해준다. 즉 단순히 스트링으로 @keyup = "textModifier"라고 해줘도 된다.

 

methods.textModifier에서는 event를 파라미터로 전달해줘서 this.text 값을 입력창의 값, event.target.value로 지정해주게 된다.

 

v-model로 양방향 바인딩

그런데... Vue.js에서는 이러한 코딩 방식을 획기적으로 줄여주는 '양방향 데이터 바인딩(Data Two Way Binding)' 이라는 방식으로 간편하게 바인딩이 가능하게 해준다!  다시 말해 input 창에 적는 값이 자동으로 data.text값으로 업데이트 되게 하기 위해서, 사용자의 입력값인 input의 value를 write값으로 바인딩 하고, textModifier 같은 메소드를 이용해서 write값을 변경해주는 방식을 하나의 키워드로 해결하는 것이다. 'v-model'이라는 키워드를 사용한다. 아래 코드를 살펴보자.

 

 

굳이 @keyup 이벤트를 만들고, textModifier 함수를 만들 필요가 없다. 그냥 v-model="내가 원하는 Data값" 으로 지정해주면 자동적으로 input 태그의 keyup, 즉 입력값과 data.write 값을 자동적으로 서로 바인딩해주게 되는 것이다.

 

다만, 위와 같이 value값을 v-bind로 묶어주는 :value="write"로 바인딩해주고, 동시에 v-model로 이벤트에 바인딩하면 작동은 되지만, 브라우저의 개발자 도구[F12]의 콘솔화면을 보면 다음과 같은 에러가 발생하므로 유의해야한다.

 

 

<input> 태그의 :value 바인딩 속성을 제거하여 에러를 해결하자.

 

 

(참고) 한글 등 조합언어 입력 문제

v-model을 사용하면 영어와 같이 한 음절에 자음과 모음의 조합이 필요없는 문자와 달리, 조합이 필요한 한국어 등의 언어는 input의 입력값을 즉각적으로 표현하지 못한다. 그래서 한글자가 완성되고 다음 글자를 입력하는 단계에서야 상태값이 변경되는 것을 볼 수 있다(input 박스에 "심층분석" 이라는 글자를 한 글자씩 작성해보자).

 

이러한 문제를 해결하기 위해서는 v-model 방식이 아니라 기존 방식대로 value 값에 data를 바인딩 하고, 메서드로 이벤트 처리를 한 뒤, 해당 이벤트를 @input 속성에 달아주는 방식을 이용해야 한다.


 

2. Computed 속성 : 메서드 결과 캐싱하기

 

computed 속성은 실제 HTML의 DOM 구조가 생성되기 전에 computed 객체 내부에 있는 값들을 계산하여 캐싱(저장)해놓고, 내부의 data값이 변경되면 추적하여 다시 계산해준다.

 

-> 뭔말인지 알아보자..

 

mustache 템플릿 내부에는 javascript 코드가 들어갈 수 있다. 그러나 복잡한 계산 로직이 들어가는 것을 비추천한다.

(공식문서 예제 : {{ message.split('').reverse().join('') }} )

가독성이 떨어지고 중복이 되는 문제가 있을 수 있기 때문이다.

 

따라서 계산부분을 따로 메서드로 빼서 작성하는게 좋지만, methods 객체에 메서드를 넣는 것이 아니라 computed 라는 객체에 입력을 해주는 게 좋다(물론 methods에 넣어도 정상작동 한다).

왜냐하면 위에서 언급한 바와 같이, computed는 미리 계산을 하여 캐싱하고 추적하므로, 속도나 중복처리 측면에서 유리하기 때문이다. 직접 코드를 만들어보자. computed.html로 파일을 만들고 다음과 같이 작성한다.

 

실행 결과를 보면, 차례대로 message, changeMessage 메서드, reverseMessage, 버튼이 출력되는 것을 볼 수 있다. computed 객체에 포함되어있는 reverseMessage는, "안녕하세요"라는 문자가 거꾸로 계산되어 반환되도록 설정되어있으므로 미리 계산된 값인 "요세하녕안"이 출력된 것을 확인할 수 있다. changeMessage 메서드는 정말 함수 자체가 출력된 것에 비해서, computed 내부의 reverseMessage 메서드는 메서드의 리턴값이 출력되었다는 것에도 유의하자.

 

reverseMessage 메서드가 참조하고 있는 this.message값이 변경되면 값이 다시 계산된다. this.message 값을 변경하기 위해 버튼을 클릭하면, @click 이벤트에 의해 changeMessage 메서드가 실행되어 message가 "안녕히 계세요~~"로 변환된다. 

 

문법상 한가지 주의할 점은 computed 부분의 메서드(reverseMessage())를 직접 호출할 때는 실행문( {{reverseMessage() }} )이 아니라 함수명만 작성 ( {{ reverseMessage }} ) 해야된다는 점이다!

 

 

 


3. Watch

 

공식문서에서 일반적으로 '선언형 프로그래밍 방식'인 computed 속성이 '표현형 프로그래밍 방식'인 watch 속성보다 좋다고 말한다. 이는 선언형 프로그래밍 방식은 목표로 하는 데이터를 지정해놓고, 그것을 이루는 데이터(변수)가 바뀌면 자동으로 추적해주는 방식인데 비하여, 표현형 프로그래밍 방식은 추적할 데이터(변수)를 하나씩 설정하기 때문에 코드가 길어질 수 있다고 표현한다.

 

아직까지 잘 모르겠지만, 내 생각에는 watch의 경우 newValue와 oldValue를 둘 다 추적하는 파라미터가 있어서 개별 데이터의 변경 전과 변경 후를 추적해야되는 상황에서는 watch가 좋을수도 있을 것 같다. 기존 computed.html에 watch 속석을 추가해보자.

 

data.message와 watch 내부의 message 메서드의 이름을 같도록 만들어 주어야 한다. 이렇게 하면 data.message의 값이 변경되는 것을 감시(watch)하고 있다가, 변경 전과 변경 후의 값(oldVal, newVal)들을 표시할 수 있다.버튼을 누르면 changeMessage가 실행되어 data.message가 변경되므로, watch가 작동하여 oldVal, newVal 값을 출력한다.

 

 


참조

1) 유튜브 코지코더 - Vue.js 2 기초 익히기 기본 강좌

www.youtube.com/channel/UCI4tTBupvhMX1aWDSm-HAXw

 

2) Vue.js 공식문서 - computed와 watch

kr.vuejs.org/v2/guide/events.html#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%88%98%EC%8B%9D%EC%96%B4kr.vuejs.org/v2/guide/computed.html

 

3) 블로그 베이스캠프 - Vue.js v-model 한글 사용문제 초간단 해결 방법

webruden.tistory.com/485

728x90
반응형