Vue3는 현재 총 7편의 시리즈로 구성되어 있습니다.
- Vue3 #0 [Vue3를 만나다]
- Vue3 #1 [변경된 기능 1 - 전역 API]
- Vue3 #2 [변경된 기능 2 - v-model] (현재글)
- Vue3 #3 [변경된 기능 3 - v-for와 v-if]
- Vue3 #4 [새로운 기능 1 - Composition API]
- Vue3 #5 [새로운 기능 2 - Teleport와 Fragments]
- Vue3 #6 [제거된 기능들]
들어가며
이번 포스팅에서는 변경된 v-model
사용법에 대해서 포스팅할 예정인데요, 이 내용은 변경된 템플릿 디렉티브에 대한 범위로 정의되어 있습니다. 다만, v-model
의 경우 실무에서 매우 자주 사용되고 있으므로 좀 자세하게 다뤄보려고 별도의 포스팅을 마련했습니다. 그럼 읽어볼까요?
v-model
v-model
은 실무에서 굉장히 자주 사용하는 템플릿 디렉티브 중 하나일 것입니다. v-model
에 변경된 부분이 있다면 아마도 필수로 짚고 넘어가야 오류를 방지할 수 있겠죠. 주요 포인트는 다음과 같이 4가지로 정리되어 있습니다.
- prop및 event사용법 변경.
.sync
수식어 제거.model
옵션이 제거되고 v-model 전달 인자로 대체.- 다중
v-model
바인딩. - 사용자 지정 수식어 생성 기능 추가.
prop및 event사용법 변경
2.x 버전에 v-model
디렉티브를 컴포넌트에 사용하는 경우입니다. 간단하죠?
<child-component v-model="inputValue"></child-component>
// 위와 동일
<child-component :value="inputValue" @input="inputValue = $event"><child-component>
prop
이나 event
이름을 변경하는 경우 2.x 버전에서는 model
옵션을 이용합니다. 현재 개발 중인 코드를 잠시 빌려 위 경우를 적용해보니 다음과 같이 바꿔볼 수 있었습니다. 대략적인 구조만 확인해주세요.
// parent
<child-component v-model="inputValue"></child-component>
// child
<template>
<input type="text" v-model="inputNumber" />
</template>
<script>
export defalut {
model: {
prop: 'number'
},
props: {
number: {
type: String,
default() {
return '';
},
}
},
computed: {
inputNumber: {
get() {
return this.number;
},
set(value) {
this.$emit('input', value);
},
},
},
}
</script>
value
로 처리되어야 하는 prop
을 number라는 이름으로 재정의하게 되면 다른 용도로 value라는 네이밍을 사용할 수 있게 됩니다.
vue3의 경우를 살펴볼까요?
기본적으로 value
는 modelValue
로, event 전달은 update:modelValue
로 변경되었습니다.
// child
<script>
export defalut {
props: {
modelValue: {
type: String,
default() {
return '';
},
}
},
computed: {
inputNumber: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
},
}
</script>
나머지는 다음 내용과 연관되므로 함께 살펴보겠습니다.
.sync 수식어 제거. model 옵션이 제거되고 v-model 전달인자로 대체
조금 전 2.x버전에서의 예제는 다음과 같이 바꿔볼 수 있습니다.
// parent
<child-component :number.sync="inputValue"></child-component>
// child
<template>
<input type="text" v-model="inputNumber" />
</template>
<script>
export defalut {
model: {
prop: 'number'
},
props: {
number: {
type: String,
default() {
return '';
},
}
},
computed: {
inputNumber: {
get() {
return this.number;
},
set(value) {
this.$emit('update:number', value);
},
},
},
}
</script>
부모 컴포넌트와의 데이터 바인딩을 update:propName
형식으로 변경하고 부모 컴포넌트에서는 .sync
수식어를 사용했습니다. 양방향 바인딩의 몇 방법 중 하나인데, 사실 실무에서는 거의 기본 방법으로만 개발해보았기 때문에 이점에 대해서는 정확한 설명을 하기 어렵네요. 이 글을 참고해보시면 도움이 될 것으로 생각됩니다.
어쨌든 히스토리를 간단히 보자면 2.0 버전에서 제거되었다가 2.3에서 부활한 방법인데 양방향 바인딩의 사용은 매우 유의해야 함을 알 수 있는 대목입니다.
그런데 Vue3에서는 .sync
수식어가 다시 제거되었네요! 이와 함께 model
옵션도 제거되면서 해당 기능을 v-model 전달 인자가 대체하도록 변경되었습니다.
// vue3
<child-component v-model:number="inputValue"></child-component>
다중 바인딩
v-model
은 vue2.x버전에서는 v-model
은 오직 하나의 바인딩만 가능했습니다. vue3버전부터는 다중으로 바인딩할 수 있습니다.
// parent
<child-component v-model:number="inputValue" v-model:text="inputText"></child-component>
// 위와 동일
<child-component
:number="inputValue"
@update:number="inputValue = $event"
:text="inputText"
@update:text="inputText = $event"
></child-component>
사용자 수식어 생성 기능 추가
이 내용은 공식 홈페이지의 내용 설명이 매우 잘 되어 있으므로 링크로 대체합니다. (https://v3.ko.vuejs.org/ko-KR/guide/component-custom-events.html##handling-v-model-modifiers)
마치며
이번 포스팅을 준비하면서 그동안 실무에서 상당히 제한적인 기능만 사용했구나… 하는 생각이 들었습니다. 제공되는 모든 기능을 적절한 곳에 활용하며 작업할 수 있도록 코드 이해도를 올려야겠습니다. 그럼 다음 포스팅에서 뵙겠습니다.