Skip to content

V-model

Vue.js에서 입력 바인딩.

간단히, v-model = v-bind:value + v-on:input 라고 이해하자.

기본 사용법

v-model 디렉티브를 사용하여 inputtextarea 엘리먼트에 양방향 데이터 바인딩을 생성할 수 있습니다. 입력 유형에 따라 엘리먼트를 업데이트 하는 올바른 방법을 자동으로 선택합니다. 약간 이상하지만 v-model은 기본적으로 사용자 입력 이벤트에 대한 데이터를 업데이트하는 Syntax sugar이며 일부 경우에 특별한 주의를 해야합니다.

사용자 정의 이벤트를 사용하여 폼 입력 컴포넌트 만들기

사용자 정의 이벤트는 v-model 에서 작동하는 사용자 정의 입력을 만드는데에도 사용할 수 있습니다. 기억하세요.

<input v-model="something">

위 문장은 아래와 같습니다.

<input
  v-bind:value="something"
  v-on:input="something = $event.target.value">

컴포넌트와 함께 사용하면 다음과 같이 간단해집니다.

<custom-input
  :value="something"
  @input="value => { something = value }">
</custom-input>

따라서 v-model을 사용하는 컴포넌트는 (2.2.0버전 이상에서 설정을 조작할 수 있습니다.)

  • value prop를 가집니다.
  • 새로운 값으로 input 이벤트를 내보냅니다.

INFORMATION

즉, v-model은 v-bind:value와 v-on:input의 조합이다

매우 간단한 통화 입력을 사용하는 모습을 보겠습니다.

<currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)">\
    </span>\
  ',
  props: ['value'],
  methods: {
    // 값을 직접 업데이트하는 대신 이 메소드를 사용하여
    // 입력 값에 대한 서식을 지정하고 배치 할 수 있습니다
    updateValue: function (value) {
      var formattedValue = value
        // 공백을 제거합니다.
        .trim()
        // 소수 자릿수 2자리로 줄입니다
        .slice(
          0,
          value.indexOf('.') === -1
            ? value.length
            : value.indexOf('.') + 3
        )
      // 값이 아직 정규화 되지 않은 경우
      // 이를 수동으로 재정의하여 조건을 충족시킵니다.
      if (formattedValue !== value) {
        this.$refs.input.value = formattedValue
      }
      // 입력 이벤트를 통해 숫자 값을 내보냅니다.
      this.$emit('input', Number(formattedValue))
    }
  }
})

위의 구현은 꽤 단순합니다. 예를 들어, 사용자는 때때로 여러 마침표와 글자를 입력 할 수 있습니다. 그렇기 때문에 보다 강력한 통화 필터를 사용할 수 있습니다.

WARNING

한글의 경우 문자가 완성되어야 정상적으로 v-model이 작동한다. 만약 완성되지 않은 글자도 적용되길 바란다면 v-model을 사용하지 말고 v-bind와 v-on을 개별로 구현해야 한다.

컴포넌트의 v-model 사용자 정의

INFORMATION

2.2.0 버전에서 추가됨

기본적으로 컴포넌트의 v-model은 value를 보조 변수로 사용하고 input을 이벤트로 사용하지만 체크 박스와 라디오 버튼과 같은 일부 입력 타입은 다른 목적으로 value 속성을 사용할 수 있습니다. model 옵션을 사용하면 다음 경우에 충돌을 피할 수 있습니다:

Vue.component('my-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    // 다른 목적을 위해 `value` prop를 사용할 수 있습니다.
    checked: Boolean,
    value: String
  },
  // ...
})
<my-checkbox v-model="foo" value="some value"></my-checkbox>

아래와 같습니다:

<my-checkbox
  :checked="foo"
  @change="val => { foo = val }"
  value="some value">
</my-checkbox>

WARNING

checked prop를 명시적으로 선언해야 합니다.

.lazy

.number

.trim

.sync

Simple Example

<input v-model="message" placeholder="여기를 수정해보세요">
<p>메시지: {{ message }}</p>

Custom Component

vue 에서 v-model 을 custom component 에서 사용 하는 방법.

App.vue

<template>
  <div class="wrapper">
    <date-picker v-model="date"></date-picker>
    <p>
      Month: {{date.month}}
      Year: {{date.year}}
    </p>
  </div>
</template>

<script>
import DatePicker from './DatePicker.vue';

export default {
  components: {
    DatePicker
  },

  data() {
    return {
      date: {
        month: 1,
        year: 2017
      }
    }
  }
})
</script>

DatePicker.vue

<template>
  <div class="date-picker">
    Month: <input type="number" ref="monthPicker" :value="value.month" @input="updateDate()"/>
    Year: <input type="number" ref="yearPicker" :value="value.year" @input="updateDate()"/>
  </div>
</template>

<script>
export default {
  props: ['value'],

  methods: {
    updateDate() {
      this.$emit('input', {
        month: +this.$refs.monthPicker.value,
        year: +this.$refs.yearPicker.value
      })
    }
  }
};
</script>

See also

Favorite site