본문 바로가기
front/vue

[vue3 공식문서 번역]Essentials.9.Form Input Bindings

by juniKang 2022. 4. 25.

프론트엔드에서 폼을 다룰 때, 종종 input 엘리먼트폼의 상태와 자바스크립트의 상태를 같게 동기화할 필요가 있다. 값을 수동으로 이어주고, 이벤트리스너를 변경하는 일은 번거로울 수 있다.

<input
  :value="text"
  @input="event => text = event.target.value">

v-model 지시어는 이런일을 보다 간단하게 만든다.

<input v-model="text">

추가로, v-model 은 <textarea>, <select> 엘리먼트같은 다른 타입의 input에도 사용할 수 있다. 사용되는 엘리먼트에 따라 자동적으로 다른 돔 프로퍼티와 이벤트의 쌍으로 확장 된다:

- <textarea> 엘리먼트와 텍스트타입인 <input>은 value 프로퍼티와 input 이벤트를 사용한다.

- <input type="checkbox">와 <input type="radio"> 는 change 이벤트와 checked 프로퍼티를 사용한다.

- <select>는 value프로퍼티를 prop으로, change를 이벤트로 사용한다.

주의
v-model은 모든 폼 엘리먼트에 있는 cehcked나 selected 어트리뷰트, 초기값을 무시할 것이다. 이건 항상 진실된 소스로 현재 바운드된 자바스크립트 상태를 다룬다. reactivity APIs를 사용해서, 자바스크립트 에서 초기값을 선언해야만 한다.

기본 사용법

Text

<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
주의
중국어, 일본어, 한국등 IME가 필요한 언어를 위해, v-model이 IME 컴포지션동안 업데이트 하지 않는 다는 걸 알아둬야 한다. 만약 이런 업데이트를 잘 응답하고 싶으면, v-model을 사용하지말고 input 이벤트 리스너와 value 바인딩을 사용하라.

Multiline text

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

<textarea> 사이에 넣은 보간법은 작동하지 않는다. v-model을 사용하라.

<!-- bad -->
<textarea>{{ text }}</textarea>

<!-- good -->
<textarea v-model="text"></textarea>

 

Checkbox

싱글 체크박스, 불린 값:

<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>

같은 배열이나 Set값에 여러개의 체크박스를 바인딩 할 수 있다:

const checkedNames = ref([])
<div>Checked names: {{ checkedNames }}</div>

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>

<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>

<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>

이 경우에, checkedNames 배여은 항상 현재 체크된 박스의 값을 담고있다.

 

Radio

<div>Pciked: {{picked }} </div>

<input type="radio" id="one" value="One: v-model="picked" />
<label for="one">One</label>

<input type="radio" id="two" value="Twp" v-model="picked" />
<label for="two">Two</label>

 

Select

단일 셀렉트:

<div>Selected: {{ selected }}</div>

<select v-model="selected">
  <option disabled value="">Please select one</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

멀티플 셀렉트 (배열로 바운드):

<div>Selected: {{ selected }} </div>

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

Sleect options는 v-for로 동적으로 렌더링 될 수 있다:

const selected = ref('A')

const options = ref([
  { text: 'One', value: 'A' },
  { text: 'Two', value: 'B' },
  { text: 'Three', value: 'C' }
])
<select v-model="selected">
  <option v-for="option in options" :value="option.value">
    {{ option.text }}
  </option>
</select>

<div>Selected: {{ selected }}</div>

 값 바인딩

라디오, 체크박스, select options를 위한 v-model  바인딩 값은 보통 정적인 문자열이다(또는 체크박스를 위한 booleans):

<!-- 'picked' 는 체크됐을 때 문자열 "a"이다->
<input type="radio" v-model="picked" value="a" />

<!-- 'toogle'은 true또는 false이다.-->
<input type="checkbox" v-model="toggle" />

<!-- 'selected'는 첫번째 옵션이 선택되었을 때 문자열 "abc" 이다.-->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

그러나 때때로 우리는 현재 활동중인 인스턴스에 동적인 프로퍼티로 값을 바인드하고 싶을 때가 있다. v-bind를 쓸 수 있다. 추가로, v-bind는 문자열이 아닌 값으로도 바인드 할 수 있다.

 

체크박스

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no" />

true-value와 false-value는 오직 v-model과 함께 동작하는 뷰의 특별한 어트리뷰트다. 이 토글 프로퍼티의 값은 box가 체크되면 'yes'가 되고, 언체크 되면 'no'가 된다. v-bind를 써서 동적인 값으로 바인드 할 수있다.

<input
  type="checkbox"
  v-model="toggle"
  :true-value="dynamicTrueValue"
  :false-value="dynamicFalseValue" />


true-value와 false-value 어트리뷰트는 input의 value 어트리뷰트와는 별개이다. 왜냐하면 부저우저들이 폼 제출에 unchecked boxes를 포함하지 않기 때문이다. 두개의 값이 폼에서 (yes나 no같은) 제출되지 않도록 확실히 하려면, radio input을 써라.

 

Radio

<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />

pick은 첫번째 라디오 인풋이 체크 됐을 때, "first"값일 것이고, 두번째가 체크됐을 때는 "second"일 것이다.

 

Select Options

<select v-model="selected">
  <!-- inline object literal -->
  <option :value="{ number: 123 }">123</option>
</select>

v-model은 문자열이 아닌 값도 바인딩을 지원한다. 위 예제에서, options이 선택되었을 때, selected는 문자 리터럴 값인 { number: 123 } 객체가 세팅될 것이다.

 

접근 제어자

.lazy

기본적으로, v-model은 각각의 input 이벤트 이후에 데이터와 input을 동기화 한다.(위에 설명한 IME 컴포지션은 제외하고) change 이벤트 이후에 동기화하도록 lazy 접근제어자를 추가할 수 있다:

<!-- "input" 대신 "change" 후에 동기화 함 -->
<input v-model.lazy="msg" />

.number

만약 숫자로 자동적으로 타입을 변경하면서 user가 입력하길 원하면, v-model 이 쓰여진 input에 number 접근제어자를 추가하면 된다:

<input v-model.number="age" />

값이 parseFloat()으로 변환되지 않는다면, 원래의 값이 대신 사용된다. number 접근제어자는 input이 type="number"라면, 자동으로 적용된다.

 

.trim

만약 공백이 자동으로 제거되길 원한다면, v-model이 쓰인 input에 trim을 추가하면 된다.

<input v-model.trim="msg" />

컴포넌트와 v-model

HTML의 내장 input 타입은 항상 필요한 건 아니다. 다행히도, 뷰 컴포넌트는 완벽하게 커스터마이징 할 수 있으며 재사용가능한 input을 만들 수 있게 도와준다. 이런 input들은 v-model과도 동작한다. 좀 더 배우고 싶다면, 컴포넌트 가이드의 Usage with v-model을 읽어보라.

댓글