v-model : two way binding
앞에서 배운 expression 혹은 v-bind는 데이터 모델을 view에 바인딩하는 one way binding 이었다. html 에서 input 같은 박스는 view의 모델 값을 변경할 수 있고. view의 변경 사항을 데이터 모델에도 반영할려면 v-model을 사용해서 two way binding을 할 수 있다.
1 |
review 컴포넌트 만들기
사용자들이 product를 보고 리뷰를 남기는 product-review 컴포넌트를 만든다.
template: input, textarea, select 박스를 각각 만든다.
data: name, review, rating 모델을 정의하고 template에 v-model로 two way binding 한다.
submit 이벤트 작성 – submit 이벤트 발생시 기본이벤트가 발생하면 페이지가 리로딩된다. 기본이벤트를 막기 위해서 preventDefault() 를 호출해야 하는데 vue에서는 간단하게 .prevent로 기본이벤트를 방지할 수 있다.
이벤트 $emit – review-submitted 이벤트를 발생시키면서 현재 입력된 데이터를 객체로 만들어서 파라메터로 보낸다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
... Vue.component('product-review', { template: ` <form class="review-form" @submit.prevent="onSubmit"> <p> <label for="name">Name:</label> <input id="name" v-model="name" placeholder="name"> </p> <p> <label for="review">Review:</label> <textarea id="review" v-model="review"></textarea> </p> <p> <label for="rating">Rating:</label> <select id="rating" v-model.number="rating"> <option>5</option> <option>4</option> <option>3</option> <option>2</option> <option>1</option> </select> </p> <p> <input type="submit" value="Submit"> </p> </form> `, data() { return { name: null, review: null, rating: null } }, methods: { onSubmit() { let productReview = { name: this.name, review: this.review, rating: this.rating } this.$emit('review-submitted', productReview); this.name = null this.review = null this.rating = null } } }); ... |
product 컴포넌트 template 맨 아래쪽에 product-review 컴포넌트를 포함시킨다.
review-submitted 이벤트를 수신한다.
수신한 데이터를 reviews에 push 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... <product-review @review-submitted="addReview"></product-review> </div> `, ... data() { return { ... reviews: [] } }, ... methods: { ... addReview(productReview) { this.reviews.push(productReview) } ... |
reviews 배열을 product 컴포넌트에서 display 해보자.
product-review 컴포넌트 바로 위에 보여준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
... <div> <h2>Reviews</h2> <p v-if="!reviews.length">There are no reviews yet.</p> <ul> <li v-for="review in reviews"> <p>{{ review.name }}</p> <p>Rating: {{ review.rating }}</p> <p>{{ review.review }}</p> </li> </ul> </div> <product-review @review-submitted="addReview"></product-review> </div> ... |
Html5 Form Validation
모든 form은 novalidate를 지정하지 않는한 html5 validation을 수행한다. 각 input 요소들은 required 를 비롯해서 9가지 종류의 validation 속성을 가질수 있다.각각의 input 요소들이 모두 valid하면 form도 valid하게 된다.
html5의 9가지 validation 중 required 속성을 알아보자. 이것은 input에 어떤 값을 입력해야 하는 속성이다.
name input에 required를 추가하고 submit을 눌러보자 html5 validation으로 인해서 브라우저에서 에러문구가 출력될것이다.
1 2 3 4 5 6 7 8 9 |
... Vue.component('product-review', { template: ` <form class="review-form" @submit.prevent="onSubmit"> <p> <label for="name">Name:</label> <input id="name" v-model="name" placeholder="name" required> </p> ... |
이런 에러문구는 브라우저마다 다 다르기 때문에 validation을 커스터마이징하게된다.