※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 직역. 의역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.
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으로 부모에게 알려주면 된다.
참고자료
'IT > 언어' 카테고리의 다른 글
[Vue.js] watch 오브젝트 (handler 유무, deep, immediate등) (0) | 2023.01.15 |
---|---|
[Vue.js] Vue.js 컴포넌트 입문 (0) | 2023.01.14 |
[Vue.js] Vue.js에서의 deep selector 그리고 작성법 (0) | 2023.01.13 |
[Vue.js] Atomic Design 베이스의 Vue 컴포넌트 설계 (0) | 2023.01.10 |
[python] 문자열을 숫자로 변환하는 int()함수가 적용되지 않는 경우와 해결법 (0) | 2023.01.03 |