Development/Vue.js

[Vue.js] Document 따라하기 - Form Input Bindings

도롱뇽도롱 2022. 6. 21. 18:00
반응형

프론트엔드에서 form을 처리할 때 form input elements의 상태를 JavaScript의 상태와 동기화해야 하는 경우가 많다. 값 바인딩을 수동으로 연결하고 이벤트 리스너를 변경하는 것은 번거로운 작업이다.

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

v-model 지시문은 위의 내용을 단순화하는데 도움이 된다.

<input v-model="text">

Form Input Bindings
Form Input Bindings

또한 v-model은 <textarea>, <select> element와 같은 다양한 유형의 입력에 사용할 수 있다. 사용되는 element에 따라 자동으로 다른 DOM 속성 및 이벤트 쌍으로 확장된다.

  • 텍스트 유형의 <input>과 <textarea>의 경우 value 속성과 input 이벤트 사용
  • <input type="checkbox">와 <input type="radio">의 경우, checked 속성과 change 이벤트를 사용
  • <select>는 value를 속성으로 사용하고 change를 이벤트로 사용

 

tip. v-model은 모든 form element에서 감지되는 초기 value, checked, selected 속성 값을 무시한다. 항상 현재 바인딩된 JavaScript 상태를 유효한 값으로 취급한다. data 옵션을 사용하여 JavaScript에서 초기 값을 선언해야 한다.

 

Basic Usage

Text

<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />

Text
Text

 

tip. 중국어, 일본어, 한국어 등과 같이 IME가 필요한 언어의 경우 IME 구성 중 v-model이 업데이트되지 않는 것을 알 수 있다. 이러한 업데이트에도 응답하려면 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>

Multiline text
Multiline text

<textarea> 태그 내부에 이중 중괄호 문법은 작동하지 않으므로 v-model을 사용해야 한다.

<!-- 잘못된 사용법 -->
<textarea>{{ text }}</textarea>

<!-- 올바른 사용법 -->
<textarea v-model="text"></textarea>

 

Checkbox

단일 체크박스는 불리언 값을 사용한다.

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

Checkbox
Checkbox

배열 또는 Set에 여러 개의 체크박스 값을 바인딩할 수도 있다.

export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
<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 배열은 항상 현재 체크된 순서대로 값을 포함한다.

Multiple Checkbox
Multiple Checkbox

 

Radio

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

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

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

Radio
Radio

 

Select

단일 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>

Single Select
Single Select

tip. v-model 표현식의 초기 값이 옵션들과 일치하지 않으면 <select> element는 선택되지 않은 상태로 렌더링된다. iOS에서는 이러한 경우 변경 이벤트를 발생시키지 않기 때문에 사용자가 첫 번째 항목을 선택할 수 없게 된다. 따라서 위의 예와 같이 비활성화된 옵션에 빈 값을 제공하는 것이 좋다.

 

다중 선택(배열로 바인딩 됨)

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

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

Multiple Select
Multiple Select

Select 옵션은 v-for를 이용하여 동적으로 렌더링 할 수 있다.

export default {
  data() {
    return {
      selected: 'A',
      options: [
        { 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>

Binding Select Options
Binding Select Options

 

Value Bindings

라디오, 체크박스, 셀렉트 옵션의 경우 v-model에 바인딩된 값은 일반적으로 정적 문자열(체크박스의 경우 불리언)이다.

<!-- 선택되었을 때 `picked`는 문자열 "a"이다. -->
<input type="radio" v-model="picked" value="a" />

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

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

그러나 때로는 현재 활성 인스턴스의 동적 속성에 값을 바인딩하고 싶을 수도 있다. 이것을 구현하기 위해 v-bind를 사용할 수 있으며 v-bind를 사용하면 입력 값을 문자열이 아닌 값에 바인딩할 수 있다.

 

Checkbox

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

Value Bindings - Checkbox
Value Bindings - Checkbox

true-value와 false-value는 v-model에서만 작동하는 Vue 전용 속성이다. 여기서 toggle 속성의 값은 체크박스가 선택되면 yes로 설정되고 선택되지 않으면 no로 설정된다. v-bind를 사용하여 동적인 값을 바인딩할 수도 있다.

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

tip. 브라우저는 form 제출 시 체크되지 않은 체크박스는 포함하지 않기 때문에 true-value와 false-value 속성은 input의 value 속성에 영향을 주지 않는다. 두 값 중 하나가 form으로 제출되도록 하려면(yes or no) radio input을 대신 사용할 것.

 

Radio

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

첫 번째 radio input이 체크되면 pick은 first의 값으로 설정되고 두 번째 radio input이 체크되면 second의 값으로 설정된다.

Value Bindings - Radio
Value Bindings - Radio

 

Select Options

<select v-model="selected">
  <!-- 인라인 객체 리터럴 -->
  <option :value="{ number: 123 }">123</option>
</select>

v-model은 문자열 값이 아닌 값의 바인딩도 지원한다. 위의 예에서 옵션이 선택되면 selected는 { number: 123 }의 객체 리터럴 값으로 설정된다.

Value Bindings - Select
Value Bindings - Select

 

Modifiers

.lazy

기본적으로 v-model은 각 input 이벤트 후 데이터와 입력을 동기화한다(위에 명시된 IME 구성 제외). Change 이벤트 후에 동기화하도록 .lazy 수식어를 추가할 수 있다.

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

Modifier - Lazy
Modifier - Lazy

 

.number

사용자 입력이 숫자로 자동 유형 변환되도록 하려면 v-model에 수식어로 .number를 추가하면 된다.

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

값을 parseFloat()로 파싱 할 수 없으면 원래 값이 대신 사용된다. input에 'type="number"'가 있으면 .number 수식어가 자동으로 적용된다.

 

.trim

.trim 수식어를 추가하여 사용자 입력의 공백이 자동으로 트리밍 되도록 설정할 수 있다.

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

Modifier - Trim
Modifier - Trim

 

v-model with Components

이 부분은 vue의 components에 대해 아직 익숙하지 않은 경우 건너뛰어도 된다.

HTML의 기본 제공 input 유형이 항상 요구 사항을 충족하는 것은 아니다. 다행히 Vue component를 사용하면 완전히 사용자 정의된 동작으로 재사용 가능한 input을 빌드할 수 있다.

v-model은 이러한 input에서도 작동한다. 자세한 내용은 component 가이드에서 읽어보시길.

 

 

관련 Repo

https://github.com/galaxyuliana/VueExercises/tree/master/first-vue-project/src/components/Exercise/08

 

참고 자료

https://vuejs.org/guide/essentials/forms.html

반응형