@iamdwins

Как передать события из компонента в слоте, в компонент родителя слота?

Использую vuejs3.
Для реализации модального окна (условно Modal.vue) с разношерстным контентом внутри, выбрал подход со слотами.
Все было прекрасно, но есть компонент с формой (условно Form.vue), при сабмите которой нужно, чтобы это модальное окно закрывалось.
Упрощенная реализация следующая:
Modal.vue
<template>
  <div class="modal" v-if="modalShow">
    <span class="modal__close" @click="toggleModalShow">x</span>

    <div class="modal__title">
      <slot name='modal-title'></slot>
    </div>
    <div class="modal__content">
      <slot name='modal-content'></slot>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {ref} from 'vue'

export const modalShow = ref<boolean>(false)

export function toggleModalShow() {
  modalShow.value = !modalShow.value
}
</script>

Form.vue
<template>
  <form @submit="fuSubmit">
    <button type="submit">Отправить</button>
  </form>
</template>
<script lang="ts" setup>
export const fuSubmit = (e:any) => {
  e.preventDefault();
}
</script>

App.vue
<template>
  <Modal>
    <template v-slot:modal-title>Форма</template>
    <template v-slot:modal-content>
      <Form/>
    </template>
  </Modal>
</template>
<script lang="ts" setup>
</script>

И от сюда вопрос, как при сабмите формы в Form.vue перехватить это событие в Modal.vue

Пробовал через emit передать, но получилось перехватить событие только в App.vue, но не в Modal.vue:
<template>
  <form @submit="fuSubmit">
    <button type="submit">Отправить</button>
  </form>
</template>
<script lang="ts" setup="{ emit }">
export const fuSubmit = (e:any) => {
  emit('modal-close');
  e.preventDefault();
}
</script>

п.с. Встречал подобные вопросы, например здесь.
  • Вопрос задан
  • 1552 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Пробовал через emit передать, но получилось перехватить событие только в App.vue, но не в Modal.vue

А вам и не надо этого делать в Modal. Событие генерируется в содержимом слота - вы не можете заранее знать, какое именно.

Ловите его в App, оттуда и управляйте видимостью окна - showModal внутри Modal не нужен, сделайте его параметром. Например.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
yarkov
@yarkov Куратор тега Vue.js
Помог ответ? Отметь решением.
С Vue3 пока не работал, но в Vue2 ЕМНИП можно как-то так сделать:
https://github.com/vuejs/vue/issues/4332#issuecomm...
Ответ написан
@Gutnov
Глобальную шину событий можно использовать
https://youtu.be/-7KCkC2YHOQ
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы