emit
<script setup>
안에서의 props
와 component와 v-model을 통한 양방향 바인딩
props 기본에 이어쓰는 포스팅
emit
1. 마크업에서 바로 emit사용
자식Component
PostCreate.vue 작성
<button @click="$emit('createEmit', 'Parameter1', 'Parameter2')">
button
</button>
2번째인자부터는 전달할 인자이다.
$emit
만을 사용할땐 아래처럼 js에서 emit
을 따로 선언할 필요가 없다.
const emit = defineEmits({
'createEmit': null,
//another Emit
'createPost': null
})
하지만 다른emit 함수($emit이 아닌 함수)와 같이 사용하려면 $emit
여도 emit에 등록해줘야한다
부모component
<script setup>
const emitTest = (param1, param2) => {
console.log('emitTest', param1, param2);
}
<script>
<template>
<PostCreate @createEmit="emitTest"></PostCreate>
</template>
emitTest Parameter1 Parameter2
2.js에서 emit 사용
자식 component
html
<input type="text" v-model="title"/>
<select v-model="type">
<option selected>Open this select menu</option>
<option value="news">뉴스</option>
<option value="notice">공지사항</option>
</select>
<button @click="createPost">
button2
</button>
input
태그에 title로 사용할 값을 입력하고 select
태그에 글의 type을 지정해주자
그리고 버튼클릭시 createPost
이벤트를 실행시키고 이벤트안에서 emit
를 실행하여 부모component에게 전달하자
js
const emit = defineEmits({
'createPost': null,
})
const createPost = () => {
emit('createPost', newPost); //부모에게 createPost 함수를 발생시킴
}
<script setup>
을 사용하지않고 <script>
를 사용할땐 setup(props, context)
에서 context를 가져오고 context에서 emit를 가져올수있다
context.emit = ['createPost']
하지만 <script setup>
에서는 context를 가져올 수 없으므로 defineEmits()
를 사용한다
부모 component
<script setup>
const createPost = (newValue) =>{
posts.push(newValue)
}
</script>
<template>
<PostCreate @createEmit="emitTest" @createPost="createPost"></PostCreate>
</template>
여기서 posts
는 지난 번 포스팅 props에서 설명하였다
3. validation 넣기
위 emit함수에 검증을 넣어줄수 있다
자식component
const emit = defineEmits({
'createEmit': null,
//validation 가능
'createPost': newValue => {
if(newValue.type || newValue.title){
return true
}
return false
},
})
component와 v-model
input
태그에는 v-model로 양방향 바인딩을 할 수 있었다.
component
에서도 양방향바인딩이 가능하다
1. modelValue 사용
부모component
TheView
<script setup>
const username = ref('defaultName');
const changeUserName = (value) =>{
username.value = value;
}
</script>
<template>
<LabelInput
:modelValue="username"
@update:modelValue="changeUserName">
</LabelInput>
{ username }
</template>
modelValue
는 양방향데이터할 key값이다. 이제 자식component의 props.modelValue
로 전달된다
즉 부모 자기자신의 username
과 자식의 props.modelValue
를 이용하여 서로 연결된다
어떤놈을 modelValue
로 선정할까? username
으로 하자! modelValue
으로 선정된 username은 값이 변경되면 changeUserName()
을 실행한다 자식놈은 이걸 props.modelValue
로 인식한다
자식component
js
const props = defineProps({
modelValue: String,
});
html
{{ label }}
<input
type="text"
:value="modelValue" <!--props.modelValue 와 같음-->
@input="event => $emit('update:modelValue', event.target.value)"
/>
2.v-model 사용
부모 component
<!-- <LabelInput
:modelValue="username"
@update:modelValue="changeUserName">
</LabelInput> -->
<LabelInput v-model="username" label="이름1"></LabelInput>
이때 username
은 changeUserName()
처럼 변경감지할때 자동으로 변수를 갱신한다
자식 component
자식 component는 딱히 코드를 추가안하여도 정상적으로 동작한다.
하지만 아래처럼 computed
를 사용하여 간단하게 줄일 수 있다
<input
type="text"
:value="modelValue"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<!-- 위 코드는 아래와 같다-->
<input v-model="value" />
js에서 computed
변수를 선언해주자
const value = computed(
{
get() {
return props.modelValue;
},
set(inputValue) {
emit('update:modelValue', inputValue);
}
}
)
const emit = defineEmits({
'update:modelValue': null,
})
3.v-model에 식별자 추가
부모 component
<LabelInput v-model:title="username" label="이름2"></LabelInput>
title
이라는 식별자 선언
이제 자식component의 props.title
로 전달된다(기존에는 props.modelValue
로 전달됨)
즉 부모 자기자신의 username
과 자식의 props.title
를 이용하여 서로 연결된다
자식 component
const props = defineProps({
//modelVue custom
title: String,
});
const value = computed(
{
get() {
return props.title;
},
set(inputValue) {
emit('update:title', inputValue);
}
}
) //html에서 computed를 사용안할땐 선언할 필요 없다
<!-- html에서 set함수 선언방법 -->
<!-- js에서 computed를 사용안할때 방법-->
<input
type="text"
:value="title"
@input="event => $emit('update:title', event.target.value)"
/>
<!-- js에서 computed를 사용할때 방법-->
<input v-model="value" />
참고자료: Vue3 완벽 마스터: 기초부터 실전까지 - “기본편”
댓글 쓰기