Vue3 상위컴포넌트로 데이터,이벤트 전달

김혁준·2024년 2월 23일
0

Vue3

목록 보기
5/5

- 이벤트 전달

  1. 컴포넌트 구조 index.vue(상위) > PostRightBar.vue(하위)
  2. PostRightBar.vue
<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 함수가 실행된다.

- 데이터 전달(+이벤트)

  1. 컴포넌트 구조 : PostRightDialog.vue(상위) > PostForm.vue(하위)
  2. PostForm.vue
<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값이 하위컴포넌트에서 바뀔때마다 바뀐 값을 실시간으로 받아서 바뀐다.

0개의 댓글

관련 채용 정보