<template>
...
...
<q-btn
padding="8px 12px 8px 8px"
unelevated
color="primary"
text-color="white"
class="full-width"
@click="$emit('openWriteDialog')"
>
...
...
</template>
<script setup>
...
...
const emit = defineEmits(['openWriteDialog']);
...
...
</script>
<style lang="scss" scoped></style>
defineEmits로 emit목록을 정의한다. 템플릿에서는 $emit으로 실행하고 script에서는 emit으로 실행한다. 위 코드에서는 클릭했을때 'openWriteDialog' 이벤트가 상위 컴포넌트로 전달된다.
3. index.vue
...
...
<PostRightBar class="col-3" @open-write-dialog="openWriteDialog" />
...
...
<script setup>
...
...
const openWriteDialog = () => {
if (!authStore.isLogin) {
$q.notify('로그인 후 이용 가능합니다!');
return;
}
postDialog.value = true;
};
...
...
</script>
<style lang="scss" scoped></style>
index.vue에 openWriteDialog를 소문자로 바꾸고 대문자있을때마다 -를 넣어서 커스텀 이벤트 리시버를 정의한다. @open-write-dialog="openWriteDialog" = 오른쪽의 내용은 해당 함수의 이름을 적는다. 그러면 PostRightBar에서 버튼을 클릭하면 openWriteDialog이벤트가 상위로 전달되고 상위에서 받은 이벤트를 수신하여 openWriteDialog 함수가 실행된다.
<template>
<q-form @submit.prevent="handleSubmit">
<q-input
v-model="titleModel"
outlined
placeholder="제목"
counter
:rules="[validateRequired]"
maxlength="40"
/>
<q-btn
type="submit"
flat
label="저장하기"
color="primary"
:loading="loading"
/>
</q-form>
</template>
<script setup>
import { computed } from 'vue';
const emit = defineEmits(['update:title','submit']);
const $q = useQuasar();
const titleModel = computed({
get: () => props.title,
set: val => emit('update:title', val),
});
const contentModel = computed({
get: () => props.content,
set: val => emit('update:content', val),
});
const handleSubmit = () => {
if (!contentModel.value) {
$q.notify('내용을 작성하세요.');
return;
}
emit('submit');
};
</script>
<style lang="scss" scoped></style>
script에서 "update:title" 이벤트 정의.
q-input에서 v-model="titleModel" 양방향 바인딩.
titleModel을 computed를 활용해서 값 변경시마다 set함수 실행.
set함수에는 실행될때마다 "update:title"이벤트와 val값을 상위컴포넌트로 전달
3. PostRightDialog.vue
<template>
<PostForm
v-model:title="form.title"
/>
</template>
<script setup>
...
...
const getInitialForm = () => ({
title: '',
});
const form = ref(getInitialForm());
...
...
</script>
<style lang="scss" scoped></style>
"update:title"에서 : 뒷부분을 상위컴포넌트에서 v-model:###여기에 적고 전달 받은 val 값을 form.title에 바인딩.
이러면 form.value.title값이 하위컴포넌트에서 바뀔때마다 바뀐 값을 실시간으로 받아서 바뀐다.