본문 바로가기
Framework&Library/뷰(Vue)

v-model에서 components에 props를 넘길 때 v-on과의 차이점

by 또몽가 2023. 6. 4.

component에서 Props 넘기거나 Event처리를 할 때 v-model과 v-on의 차이에 대해.

1. v-model

v-model은 form 입력 요소 또는 구성 요소에서 양방향 바인딩을 만듭니다. v-model의 사용은 다음과 같은 태그와 component에 한정되어 사용됩니다. 참고 링크

  • <input>
  • <select>
  • <textarea>
  • components

2. Component v-model

component에 props를 넘길 때 양방향 바인딩이 요구되는 경우 v-model이 사용됩니다.

먼저 component에서 v-model이 사용되는 경우입니다. v-model을 HTML 상의 태그에서 활용하려고 할 경우 <input>, <select>,<textarea>와 같은 form 구성 요소에서 주로 활용됩니다.

<input v-model="searchText" />

v-model 은 v-bind와 v-on의 기능의 조합으로 동작한다. 매번 사용자가 일일이 v-bind와 v-on 속성을 다 지정해 주지 않아도 좀 더 편하게 개발할 수 있게 합쳐져서 만들어진 문법입니다.

v-model의 속성을 들여다보면,

  • v-bind : 속성은 vue instance의 데이터 속성을 해당 HTML요소에 연결할 때 사용.
  • v-on : 속성은 해당 HTML요소의 이벤트를 Vue instance의 로직과 연결할 때 사용.
  사용자 이벤트에 의해 실행된 뷰 메서드(methods) 함수의 첫 번째 인자에는 해당 이벤트(event)가 들어온다

그렇기에, 위의 코드를 보다 정확하게 표현하면 다음과 같습니다

<input
  :value="searchText"
  @input="searchText = $event.target.value"
/>

v-model 을 components 요소에서 사용할 경우 다음과 같이 확장될 수 있습니다.

<CustomInput
:modelValue="searchText"
@update:modelValue="newValue => searchText = newValue"
/>

그리고 v-model 을 component에서 사용하면 다음과 같습니다.

<CustomInput v-model="searchText" />

3. v-model로 인자(arguments)전달

기본적으로 v-model component 에서 modelValue의 props를 사용하거나 update:modelValue 이벤트로 사용되고 v-model 의 인자는 다음과 같이 사용될 수 있습니다.

<MyComponent v-model:title="bookTitle" />

이 경우 자식 component 요소는 title props와 update:title 이벤트를 내보내 부모 값을 업데이트해야 합니다. 참고자료

<!-- MyComponent.vue -->
<script>
export default {
props: ['title'],
emits: ['update:title']
}
</script>
<template>
<input
type="text"
:value="title"
@input="$emit('update:title', $event.target.value)"
/>
</template>

4. vue2와 vue3의 v-model의 차이점

<!-- 부모 컴포넌트에서의 코드 -->

<!-- v-model로 축약되기 전 방식 -->
<ChlidComponent :value="자식컴포넌트와 동기화 시킬 데이터 이름" @input="자식컴포넌트와 동기화 시킬 데이터 이름=$event"/>
<!-- v-model로 축약한 방식 -->
<ChlidComponent v-model="자식컴포넌트와 동기화 시킬 데이터 이름"/>

vue2에서는 component에 v-model을 사용하는 것이 value prop을 전달하고 input 이벤트를 emit 하는 것과 같았습니다.

부모 component에서 데이터 prop을 통해 자식 component로 데이터를 전달하고, 그 데이터를 전달받은 자식 component는 이벤트 전달($emit)을 통해 다시 부모로 보내주는 구조라고 이해하면 됩니다. 이것을 Vue2 / Vue3에선 v-model이라는 디렉티브 하나로 기능을 내포하여 사용할 수 있도록 해 준 것입니다. 참고블로그

Vue2에서 자식컴포넌트에서는 부모 component에서 value 라는 이름에 담은 자식 component와 동기화 시킬 데이터를 props로 받고, modeling을 통해서(Vue2 기준) 커스터 마이징을 합니다.

vue3에서 component의 v-model은 modalValue prop 를 전달하고 update:modelValue 이벤트를 emit하는 것과 같습니다. 추가적으로 여러 개의 v-model 을 가질 수 있습니다.

5. Form Input Bindings

frontend에서 양식을 처리할 때 양식 입력 요소의 상태를 JavaScript의 해당 상태와 동기화해야 하는 경우가 많습니다. 값 바인딩을 수동으로 연결하고 이벤트 리스너를 변경하는 것은 번거로울 수 있습니다.

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

v-model은 위의 내용을 다음과 같이 단순화하는 데 도움이 됩니다.

<input v-model="text">

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

  • 텍스트 유형의 <input> 과<textarea> 요소는 값 속성과 input 이벤트에서 사용합니다.
  • <input type="checkbox"> 과 <input type="radio">는 check props나change 이벤트 사용합니다.
  • <select> 는 이벤트의 변화나 props와 같은 value 를 입력할 때 사용됩니다.

6. v-model과 v-on의 차이점

v-model

input과 textarea element 에 양방향 데이터 바인딩을 생성할 수 있습니다. 연결을 해두면 자동으로 업데이트 됩니다.

message input 에 값을 입력하면 밑에 변수에 바로 바인딩 되어 나옵니다.

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

**v-on :**dom 이벤트가 트리거 될 때 js를 실행할 수 있는 이벤트 리스너로 v-on을 줄여서 @로 작성합니다.

이벤트의 종류

  • click : 마우스로 클릭했을 때 실행되는 이벤트
  • dblclick: 마우스로 더블 클릭했을 때 실행되는 이벤트
  • mouseover : 마우스 포인트가 해당 요소에 올라왔을 때 실행되는 이벤트
  • mouseout : 마우스 포인트가 해당 요소를 벗어났을 때 실행되는 이벤트
  • mousemove : 마우스 포인트가 이동했을 때(움직일 때) 실행되는 이벤트
  • mousedown : 마우스가 버튼을 눌렀을 때 실행되는 이벤트
  • mouseup : 마우스가 버튼을 놓았을 때 실행되는 이벤트
  • keyup : 키보드 키를 놓았을 때 실행되는 이벤트
  • keydown : 키보드 키를 눌렀을 때 실행되는 이벤트
  • keypress : 키보드 키를 눌렀다가 놓았을 때 실행되는 이벤트
  • change : 요소가 변경될 때 실행되는 이벤트
  • submit : form 태그에서 제출될 때 실행되는 이벤트
  • reset : form 태그에서 reset할 때 실행되는 이벤트
  • select : select 태그의 값이 선택되었을 때 실행되는 이벤트
  • focus : 태그에 focus되어 있을 때 실행되는 이벤트
  • blur : 태그가 focus 를 잃었을 때 실행되는 이벤트

결론

  • v-model은 components 에서 부모 자식 간의 인자를 넘길 때 사용될 수 있습니다. 다만 주로 사용에 제한되는 태그가 <input> , <select> , <textarea> 이므로 이를 부모, 자식 요소에서도 고려하여 사용하여야 합니다. 그 외의 이벤트에서는 v-on 을 사용하여야 합니다.

참고자료

공식 문서)

v-model

Built-in Directives | Vue.js

Form Input Bindings

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

Component v-model

https://vuejs.org/guide/components/v-model.html

blog)

https://sungjaecloud.tistory.com/354

https://sso-feeling.tistory.com/675