Как правильно добавить прослушиватель событий в дочернее окно в vuejs?

Из компонента в vue 3 мне нужно было новое окно, похожее на всплывающее окно, с помощью window.open(url, name, config). И мне нужно вызвать функцию, когда дочернее окно закрыто.

(Обратите внимание, что это не относится к событиям дочернего-родительского компонента или наоборот, а скорее к оконному объекту и его родителю)

Я попытался добавить прослушиватели событий во всплывающее окно, но они уничтожаются, когда URL-адрес перенаправляется в дочернее окно.

На вкладке скрипта компонента добавлен метод для открытия нового окна и выполнения другой обработки по нажатию кнопки, как показано ниже:

<template>
    ....
    <button @click = "onPositive"></button>
</template>

<script lang = "ts">
export default defineComponent({
    methods: {
        onPositive() {
           const popup = window.open(url, name, config) as Window
           popup.focus()

           // method 1:
           popup.addEventListener('beforeunload' () => {
               console.info("event triggered)
               this.onPopupClosed
           })

           // method 2:
           popup.onbeforeunload = () => {
               console.info("event triggered)
               this.onPopupClosed
           }
       },

       onPopupClosed() {
            // .....
       }
    }
})
</script>

Я попытался добавить различные прослушиватели событий, такие как 2 метода, упомянутые выше, но он все еще не срабатывает.

Некоторые идеи:

  1. URL имеет другое происхождение.
  2. Прежде чем URL-адрес перенаправляется, когда я закрываю дочернее окно, он срабатывает.
  3. Использование Vue.js 3 и typescript 5.

🤔 А знаете ли вы, что...
JavaScript может выполняться как на стороне клиента (в браузере), так и на стороне сервера (с использованием Node.js).


53
1

Ответ:

Решено

Если всплывающее окно находится под вашим контролем, вы можете сделать что-то вроде этого.

В последнем месте, когда вся навигация сделана

<script>
window.addEventListener('beforeunload', () => {
  window.opener.postMessage('popup-closed', '*');
});
</script>

window.opener.postMessage() — это метод, который обеспечивает связь между текущим окном (дочерним окном) и окном, которое его открыло (родительское окно). Он предоставляет способ отправки сообщений между двумя окнами, даже если они из разных источников (т. е. из разных доменов, протоколов или портов).

В вашем родительском компоненте vue

... 

// Listen for messages from the child window
window.addEventListener('message', (event) => {
  if (event.data === 'popup-closed') {
    onPopupClosed();
  }
});

const onPopupClosed = () => {
  // Handle the event when the child window is closed
  console.info('Popup closed');
};

window.addEventListener('message', ...) — это прослушиватель событий на JavaScript, который позволяет прослушивать сообщения, отправленные из других окон или фреймов на веб-странице. Он обеспечивает связь между разными окнами или фреймами на одной странице или через разные домены, протоколы или порты.

Еще одна вещь: свойство window.opener всегда относится к родительскому окну, которое открыло дочернее окно, независимо от любого промежуточного перехода к другим URL-адресам. Когда дочернее окно открывается с помощью window.open() из родительского окна, ссылка на родительское окно остается неизменной на протяжении всего времени существования дочернего окна, даже если дочернее окно переходит к другим URL-адресам до перехода к конечному пункту назначения.