폼 입력바인딩 (v-model)

component-vmodel


폼 입력바인딩 (v-model)


  1. 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">


  2. 다양한 폼 요소 지원: v-model은 다음과 같이 다양한 타입의 폼 요소를 지원합니다.

    • 텍스트 입력(<input><textarea>): value 속성과 input 이벤트를 사용합니다. ( 앞서 설명한 1번 예제 )

    • 체크박스(<input type="checkbox">): checked 속성과 change 이벤트를 사용합니다.

    • 라디오 버튼(<input type="radio">): checked 속성과 change 이벤트를 사용합니다.

    • 드롭다운(<select>): value 속성과 change 이벤트를 사용합니다.


  3. 기본 사용법:

    • 텍스트 입력: <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>


  4. IME 이슈: 한국어, 중국어, 일본어 등 IME(입력기)를 필요로 하는 언어에서는 v-model이 IME 구성 중에 업데이트되지 않을 수 있습니다.

    이 경우에는 직접 input 이벤트 리스너와 value 바인딩을 사용해야 합니다. (즉 v-model이 아니라 value와 Input함수를 사용하라는거)


  5. 수식어(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>

test

반응형과 연관해서 생각해봄

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의 값을 갱신할수있다

(좀 더 간단하게 양방향 바인딩 가능)



참고

폼 입력바인딩 (v-model)

부모 자식 컴포넌트에서 v-model을 사용한 양방향 바인딩

Feb 4, 2024 Views 147