IT/언어

[Vue.js] v-model 이란?

개발자 두더지 2023. 1. 13. 18:54
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 직역. 의역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다. 

 

 

v-model이란


 공식 사이트를 인용하면 다음과 같다. 

 form의 input 요소나 textarea요소, select 요소에 쌍방향(two-way) 데이터 바인딩을 만들고 싶을 때, v-model 디렉티브를 사용할 수 있다.

 너무 짧아서 알기 어렵다.

 v-model의 역할은 "변경과 데이터를 엮어주는 것"이라고 할 수 있다. 즉,  (1) 표시할 데이터 (2) 변경이 있다면 데이터에 반영 이 두 가지를 세트로 한 것이 쌍방향(two-way) 데이터 바인딩이며, 이것을 v-model이 해준다는 것이다.

 사용하자면 다음과 같이 쓸 수 있다.

<template>
  <input v-model="username" />
  <p>username: {{ username }}</p>
</template>

<script>
// 초기치로써 username가 input에 전달되어 있다.
// input의 변경이 username에 반영된다.
export default {
  data: () => {
    return {
      username: "username"
    };
  }
}
</script>

 보았듯, 입력란과 데이터가 쌍방향으로 링크되어 연동되고 있음을 알 수 있고, 이것을 v-model이 해주고 있다는 것이다. 

 

 

v-model 해부해보기


 또 다시 공식 사이트를 인용해보자면,

v-model은 유저의 입력 이벤트에 따라 데이터를 변경위한 기본적인 syntax sugar로, 그에 더불어, 몇 가지의 엣지 케이스에 대해서 특별한 배려를 해준다.

 v-model은 syntax sugar, 즉 무언가의 생략 기법, v-model은  하나의 기능이 아닌 여러 기능의 조합으로 이루어진 구조로 되어 있다는 것이다.

 "(1) 표시할 데이터 (2) 변경이 있다면 데이터에 반영하는 조합"은 요소마다 아래와 같이 정해져 있다.

  • 텍스트와 여러 행의 텍스트는 value 속성과 input 이벤트를 사용한다.
  • 체크박스와 라디오 박스는 checked 속성과 change 이벤트를 사용한다.
  • 선택 필드는 value 속성과 change 이벤트를 사용한다.

 다음의 예는 "텍스트"이므로, value와 input으로 전개하는 것이 가능하다.

<template>
  <input v-model="username" />
  <input :value="username" @input="username = $event.target.value" />
  <p>username: {{ username }}</p>
</template>

<script>
// v-model과 value-input이 완전히 같은 동작을 하고 있다.
export default {
  data: () => {
    return {
      username: "username"
    };
  }
}
</script>

 

 

 

컴포넌트에서의 사용법


 계속해서 자체 제작한 컴포넌트안에서의 v-model를 사용하고자하면 "props로 전달한 그 값을 v-model 에 대입하면 해결되는 것인가?" 라고 생각했지만 에러로 생각대로 되지 않았던 경험이 있지 않은가? 이것은 Vue 컴포넌트의 props가 일방 통행이기 때문이다. 

//Child.vue

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

<script>
export default {
  props: ['value']
}
</script>
//Parents.vue

<template>
  <div>
    <child v-model="username"></child>
  </div>
</template>

<script>
import Child from "@/components/child";

export default {
  components: {
    Child
  },
  data() {
    return {
      username: "username"
    }
  }
}
</script>

 위 자식 컴포넌트와 부모 컴포넌트 코드를 해설하자면 다음과 같다.

1. 부모 컴포넌트에서 자식 컴포넌트의 v-model은 :value와 @input로 해설된다.

2. 자식 컴포넌트의 <input>에는 value(username)이 전해진다.

3. 자식 컴포넌트의 <input>에 입력이 있다면 emit으로 부모의 v-model에 $event.target.value가 전달되는 것으로 username에 값이 반영된다.

 props 자체는 변경하지 않고, 변경된 것을 emit으로 부모에게 알려주면 된다.


참고자료

https://qiita.com/al_tarte/items/0ff49219cd1b25411b7a

728x90