폼 입력바인딩 (v-model)
v-model값 바인딩: Vue에서는
v-model
디렉티브를 사용하여 폼 입력 요소(input, textarea, select 등)의 값과 데이터를 쉽게 양방향 바인딩할 수 있습니다.일반적인사용 예제 (value , input함수 사용)
<input :value="text" @input="event => text = event.target.value"> // value로 값이 입력된고 input으로 값이 변경된다
v-model 사용시 ( v-model로 value와 input함수 대체 )
const text=ref('') // input입력시 양방향으로 자동으로 갱신 <input v-model="text">
다양한 폼 요소 지원:
v-model
은 다음과 같이 다양한 타입의 폼 요소를 지원합니다.텍스트 입력(
<input>
및<textarea>
):value
속성과input
이벤트를 사용합니다. ( 앞서 설명한 1번 예제 )체크박스(
<input type="checkbox">
):checked
속성과change
이벤트를 사용합니다.라디오 버튼(
<input type="radio">
):checked
속성과change
이벤트를 사용합니다.드롭다운(
<select>
):value
속성과change
이벤트를 사용합니다.
기본 사용법:
텍스트 입력:
<input v-model="message" />
여러 줄 텍스트:
<textarea v-model="message"></textarea>
체크박스:
<input type="checkbox" v-model="checked" />
라디오 버튼:
<input type="radio" v-model="picked" />
드롭다운:
<select v-model="selected">...</select>
IME 이슈: 한국어, 중국어, 일본어 등 IME(입력기)를 필요로 하는 언어에서는
v-model
이 IME 구성 중에 업데이트되지 않을 수 있습니다.이 경우에는 직접
input
이벤트 리스너와value
바인딩을 사용해야 합니다. (즉 v-model이 아니라 value와 Input함수를 사용하라는거)수식어(Modifiers):
.lazy
: 입력 필드에서input
이벤트 대신change
이벤트 후에 동기화를 하고 싶을 때 사용합니다..number
: 입력 값을 자동으로 숫자로 변환합니다..trim
: 입력 값을 공백 없이 트리밍합니다.
부모컴포넌트와 자식컴포넌트 간에 v-model을 사용한 양방향 바인딩 예제
Vue 3.4부터는 defineModel()
매크로를 사용하는 것이 권장되는 접근 방식입니다
아래의 예제는 부모와 자식간의 v-model로 양방향 통신을 하는 예제를 다룸
1. 기본적인 컴포넌트에 단일 v-model 바인딩 사용 예제
부모컴포넌트 (Parent.vue)
<template>
<ChildComponent v-model="childInput" />
<!--이름이 있을 경우 -->
<!-- <ChildComponent v-model:title="bookTitle" /> -->
<p>자식 컴포넌트의 입력값: {{ childInput }}</p>
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const childInput = ref('')
</script>
자식 컴포넌트 (ChildComponent.vue)
<template>
<input type="text" v-model="modelValue" />
<!--이름이 있을 경우 -->
<!-- <input type="text" v-model="title" /> -->
</template>
<script setup>
import { defineModel } from 'vue'
const modelValue = defineModel()
// 이름이 있을 경우
// const title = defineModel('title')
// v-model을 필수로 만들기
// const model = defineModel({ required: true })
// 기본값 제공
// const model = defineModel({ default: 0 })
</script>
2. 하나의 컴포넌트에 다중 v-model 바인딩 사용 예제
내가 기존에 해왔던 프로젝트 방식 "defineEmits(['update:firstName', 'update:lastName'])"등은 필요하지않다 (새로운 3.4부터)
부모컴포넌트 (Parent.vue)
<template>
<div>
<UserForm
v-model:first-name="firstName"
v-model:last-name="lastName"
/>
<p>FullName: {{ firstName }} {{ lastName }}</p>
</div>
</template>
<script>
import UserForm from './UserForm.vue';
export default {
components: {
UserForm
},
data() {
return {
firstName: '',
lastName: ''
}
}
}
</script>
자식 컴포넌트 (UserForm.vue)
<template>
<div>
<input type="text" v-model="firstName" placeholder="이름" />
<input type="text" v-model="lastName" placeholder="성" />
</div>
</template>
<script setup>
import { defineModel } from 'vue';
const firstName = defineModel('firstName');
const lastName = defineModel('lastName');
</script>
반응형과 연관해서 생각해봄
2024/5/16
const text=ref('')
<input :value="text">
input에 값을 입력할 경우 text는 변경되지 않는다 (단방향 바인딩)
( :value는 기본적으로 input이 가지는 속성)
( text의 값을 직접 text.value등으로 변경하면 input에 입력된 text의 값은 변경되는 상태임)
const text=ref('')
<input
:value="text"
@input="event => text = event.target.value">
위와 같이 사용하면 input에 값을 입력할 경우 emit가 발생해서 text의 값을 갱신한다
(양방향 바인딩)
const text=ref('')
<input v-model="text">
위의 예제처럼 v-model을 사용하면 input입력사 text의 값을 갱신할수있다
(좀 더 간단하게 양방향 바인딩 가능)
참고