[vue3] defineModel 매크로 (v-model 간소화)

ShinYe's·2024년 4월 23일

vue 3.4ver 부터는 defineModel() 매크로 사용이 권장된다.
Composition API에서 사용됨

defineModel( ) 매크로

  • const model = defineModel('props', {default: '기본값', required: true})
    ① 모델 prop, ② 값 업데이트 이벤트를 선언한다.
  • v-model을 간소화 하여 직접 바인딩된 값 조작 가능(props+emits자동 설정)
  • 첫번째 인수가 문자열이면 prop이름으로 지정, 없으면 modelValue로 기본 지정된다.
  • 값이 변경될 때 update:modelValue를 통해 이벤트가 발생된다.

💡 기본

1) prop명 modelValue, data타입 String

const model = defineModel({ type: String })

2) prop명 count, data타입 Number, 기본값 0 , 필수 지정

const count = defineModel('count', { type: Number, default: 0 , require: true})

3) prop값 변경(update:modelValue 실행)

model.value = 'Hello';

💡 심화

//children 컴포넌트
<template>
  <input type='text' v-model='model'/>
</template>
<script setup>
	const model = defineModel('text')	
</script>

//parent 컴포넌트
<template>
  <children v-model:text='title'></children>
</template>
<script setup>
  	import { ref } from 'vue';
	import children from './children.vue'
	const title= ref('내용입력');
</script>

1) v-model에는 반응형 변수를 바인딩한다.
v-model:text='내용입력' 과 같은 하드코딩이 아닌 v-model:text='title' 형태, ref로 선언한 변수 사용
2) defineMode의 prop에 default값을 지정할 경우 부모 컴포넌트에서 해당 prop값을 지정하지 않을 경우 동기화 문제가 발생할 수 있다.

이전 방식

//children 컴포넌트
<template>
	<input :value="props.modelValue"
	@input="$emit('update:modelValue', $event.target.value)"
	/>
</template>
<script setup> 
	const props = defineProps(['modelValue']);
	const emit = defineEmits(['update:modelValue']);
</script>

//parent 컴포넌트
<script setup>
import { ref } from 'vue'
import children from './children.vue'

const title = ref('예제연습')
</script>

<template>
  <h1>{{ title }}</h1>
  <MyComponent v-model="title" />
</template>
  • 양방향 바인딩을 사용하기 위해 props와 emits을 지정한 다음 부모 컴포넌트에서 v-model로 prop값을 넘겨준다.

+) 이전방식 추가 예제

  • props 명 title로 지정해서 사용
//children 컴포넌트
<template>
  <input
    type="text"
    :value="title"
    @input="$emit('update:title', $event.target.value)"
  />
</template>
<script setup>
  defineProps(['title'])
  defineEmits(['update:title'])
</script>

//parent 컴포넌트
<template>
  <h1>{{ title }}</h1>
  <MyComponent v-model:title="title" />
</template>
<script setup>
  import { ref } from 'vue'
  import MyComponent from './MyComponent.vue'

const title = ref('예제입력')
</script>
profile
성장중인 새싹 개발자 🌱

0개의 댓글