vmodel.gif

참고 자료

Qiita
커스텀 컴포넌트


양방향 데이터 바인딩

Vue.js 에서 정말 자주 사용하는 디렉티브에는 'v-model'이 있습니다. 양방향 데이터 바인딩에 사용되며 특히 input과 같이 사용자의 데이터 입력을 편리하게 받을 수 있습니다.

  • input의 value값을 수정하면, data의 message가 변경되고
  • data의 message를 수정하면 input의 value값 역시 변경됩니다.

<div id="app">
    <input v-model="message" type="text">
    <div> {{ message }}</div>
</div>


<script>
    new Vue({
        el: '#app',
        data: {
            message: '너와 나의 연결고리'
        },
    })
</script>

마법같이 사용자의 입력값이 데이터로 들어가는데요. 그런데 어떻게 작동하는 것일까요?

먼저, 공식문서에 보면 다음과 같이 적혀있습니다.
v-model은 기본적으로 사용자 입력 이벤트에 대한 데이터를 업데이트하는 syntax sugar이며 일부 경우에 특별한 주의를 해야합니다.

정리하면 syntax sugar란

  • 프로그래밍 언어를 더 분명하고, 간결하게 표현하거나, 선호하는 대체 스타일로 표현하는 것.
  • 예시) a = a + b; => a += b;

그렇다면 v-model은 무엇을 간결하게 표현한 것일까요?

위에 v-model을 사용한 코드는 v-model 없이 다음과 같이 바꿀 수 있습니다.
1) 사용자의 입력이 감지되면 input 이벤트가 감지되고 $event.target.value를 인자값으로 받습니다.

2) 이벤트 값인 $event.target.value은 data의 message 를 갱신합니다.

3) message의 변경에 따라 :value가 변경됩니다.

<div id="app">
    <input :value="message" @input="message = $event.target.value" type="text">
    <div> {{ message }}</div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            message: '너와 나의 연결고리'
        },
    })
</script>

v-model="message"라고 하면 1):value="message", 2) @input="message = $event.target.value" 과 같은 역할을 수행합니다.

부모컴포넌트에서 사용자가 정의한 input 컴포넌트를 사용하는 경우

1) 자식 컴포넌트에서 입력이 발생하면 input event가 감지되고 부모의 input 이벤트로 $event.target.value를 인자값으로 함께 넘겨줍니다.

2) 부모 컴포넌트에서 input 이벤트를 감지하고 data의 message를 변경해줍니다.

//child component

<template>
    <input @input="$emit('input', $event.target.value)">
</template>

<script>
export default {
  name: 'ChildInput',
}
</script>

//parent component

<template>
    <child-input v-model="message">
</template>

<script>
import Vue from 'vue'
import ChildInput from '../components/common/ChildInput.vue'
Vue.component(child-input', ChildInput)

export default {
  name: 'Parent',
  data () {
    return  {
      message: ''
    }
  }
}
</script>

궁금한것이자 알아야 할것

이렇게 보면 v-model은 v-bind:value 와 v-on:input 을 단순히 하나로 만든 것과 같아 보이지만, 차이가 존재합니다.

위의 input은 v-bind:value 와 v-on:input 로 구현된것
아래의 input은 v-model로 구현된것

ezgif.com-gif-maker.gif

한글, 일본어, 중국어의 경우 v-model을 사용하면 아래와 같이 입력값에 바로 반응하는 것이 아니라 뭔가 끊기는 느낌이 듭니다..

공식문서에 보면 IME (중국어, 일본어, 한국어 등)가 필요한 언어의 경우 IME 중 v-model이 업데이트 되지 않습니다. 이러한 업데이트를 처리하려면 input 이벤트를 대신 사용하십시오. 라고 되어있습니다..

그렇다면 v-model에는 1) v-bind:value, 2) v-on:input 말고, 더 추가된것이 있는 거 같은데... 모르겠네요