Vue.js 를 배워보자

Vue.js에서 팝업 구현하기: 부모 창에서 호출하고 별도 윈도우로 열기 (window.open() 활용)

_Blue_Sky_ 2024. 11. 25. 20:44
728x90
728x90

웹 애플리케이션을 개발하다 보면, 팝업 창을 활용해야 하는 상황이 자주 발생합니다. 예를 들어, 로그인 화면을 별도의 팝업 창에서 처리하거나, 대화형 데이터 입력 폼을 독립된 창으로 열어야 할 때가 있습니다. Vue.js에서 이런 팝업 창을 구현하려면 window.open() 메서드를 활용하면 간단하게 구현할 수 있습니다. 이번 글에서는 부모 창에서 특정 버튼을 클릭하여 별도의 팝업 창을 열고, 이 팝업 창에서 작업을 수행한 뒤 결과를 부모 창으로 반환하는 방법을 자세히 알아보겠습니다. 여기서는 window.open()의 주요 옵션과 Vue 컴포넌트에서 이를 제어하는 실습 예제를 통해 팝업 창을 구현하는 방법을 단계별로 설명합니다. 키워드는 Vue.js, 팝업 구현, window.open(), 부모-자식 통신, 팝업 옵션 설정, 메시지 전달, 데이터 공유, 이벤트 핸들링, 브라우저 팝업 차단, 팝업 창 스타일링, Vue 상태 관리입니다.


1. window.open() 이해하기

window.open()은 브라우저에서 새 창을 열기 위한 메서드로, 첫 번째 인자로 URL, 두 번째 인자로 창 이름, 세 번째 인자로 옵션 문자열을 전달할 수 있습니다. 예를 들어 다음과 같은 코드를 사용하면 새로운 팝업 창을 열 수 있습니다.

window.open('https://example.com', 'popupWindow', 'width=600,height=400,scrollbars=yes');

위 코드에서:

  • https://example.com: 팝업 창에 로드할 URL입니다.
  • popupWindow: 팝업 창의 이름 또는 식별자입니다.
  • width=600,height=400,scrollbars=yes: 팝업 창의 크기 및 옵션 설정입니다.

728x90

2. Vue 컴포넌트에서 팝업 열기

Vue 컴포넌트에서 팝업 창을 열려면 이벤트 핸들러와 함께 window.open()을 호출하면 됩니다. 다음은 버튼 클릭으로 팝업을 여는 기본 예제입니다.

부모 컴포넌트 (ParentComponent.vue)

<template>
  <div>
    <h1>부모 컴포넌트</h1>
    <button @click="openPopup">팝업 열기</button>
  </div>
</template>

<script>
export default {
  methods: {
    openPopup() {
      const popupUrl = '/popup'; // 팝업에 표시할 경로
      const popupName = 'PopupWindow';
      const popupOptions = 'width=600,height=400,scrollbars=yes';

      // 팝업 창 열기
      const popup = window.open(popupUrl, popupName, popupOptions);

      if (popup) {
        // 부모에서 팝업 창에 메시지 보내기
        popup.onload = () => {
          popup.postMessage({ message: 'Hello from parent' }, '*');
        };
      } else {
        alert('팝업 창이 차단되었습니다.');
      }
    },
  },
};
</script>

3. 팝업 창 구현

팝업 창은 Vue 라우트나 별도의 Vue 컴포넌트로 구현할 수 있습니다. 아래는 팝업 창에서 부모로부터 메시지를 받고, 다시 부모로 메시지를 반환하는 예제입니다.

팝업 컴포넌트 (PopupComponent.vue)

<template>
  <div>
    <h1>팝업 창</h1>
    <p>부모로부터 받은 메시지: {{ parentMessage }}</p>
    <button @click="sendMessageToParent">부모에게 메시지 보내기</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      parentMessage: '',
    };
  },
  mounted() {
    // 부모로부터 메시지 받기
    window.addEventListener('message', this.receiveMessage);
  },
  beforeDestroy() {
    window.removeEventListener('message', this.receiveMessage);
  },
  methods: {
    receiveMessage(event) {
      if (event.origin !== window.location.origin) return; // 보안 체크
      this.parentMessage = event.data.message;
    },
    sendMessageToParent() {
      // 부모 창에 메시지 보내기
      window.opener.postMessage({ message: 'Hello from popup' }, '*');
    },
  },
};
</script>


4. Vue Router 설정

PopupComponent.vue를 /popup 경로에 연결하려면, 먼저 Vue Router를 설정해야 합니다. 프로젝트에 Vue Router가 이미 설정되어 있다면 다음과 같이 경로를 추가합니다.

router/index.js (혹은 라우터 설정 파일)

import { createRouter, createWebHistory } from 'vue-router';
import ParentComponent from '@/components/ParentComponent.vue';
import PopupComponent from '@/components/PopupComponent.vue';

const routes = [
  {
    path: '/',
    name: 'Parent',
    component: ParentComponent, // 부모 컴포넌트
  },
  {
    path: '/popup',
    name: 'Popup',
    component: PopupComponent, // 팝업 컴포넌트
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

5. Vue Router 등록

이제 Vue 애플리케이션에 라우터를 등록합니다. main.js 파일에서 router를 등록하여 애플리케이션이 URL에 따라 컴포넌트를 렌더링하도록 합니다.

main.js

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);
app.use(router);
app.mount('#app');

6. 팝업 창에서 /popup 경로로 라우트 연결

window.open('/popup')는 브라우저가 애플리케이션의 /popup 경로를 요청하도록 만듭니다. Vue Router는 이 요청을 받아서 PopupComponent.vue를 렌더링합니다. 이제 팝업 창에서 Vue 애플리케이션의 해당 컴포넌트를 볼 수 있습니다.


7. 부모와 팝업 간의 데이터 통신

부모와 팝업 간의 데이터 통신은 postMessage API를 활용하여 이루어집니다. 이를 통해 두 창이 서로 메시지를 주고받을 수 있습니다. 위의 예제에서 팝업 창은 window.opener.postMessage()를 사용하여 부모로 메시지를 보냅니다. 반대로 부모는 팝업 창의 postMessage를 호출하여 데이터를 전달할 수 있습니다.


728x90

8. 팝업 창 옵션 및 사용자 경험 개선

window.open()에서 사용하는 옵션은 사용자 경험에 큰 영향을 미칩니다. 다음은 유용한 옵션 설정입니다:

  • width와 height: 팝업 창의 크기를 지정합니다.
  • left와 top: 팝업 창의 화면 위치를 지정합니다.
  • scrollbars=yes: 스크롤바를 활성화하여 작은 화면에서도 콘텐츠를 볼 수 있게 합니다.
  • resizable=yes: 창 크기 조정을 허용합니다.

9. 브라우저 팝업 차단 문제 해결

팝업 차단은 브라우저의 보안 설정에 따라 발생할 수 있습니다. 이를 방지하려면 팝업 창 열기를 사용자 동작(예: 버튼 클릭)과 연결해야 합니다. 예를 들어, Vue의 @click 이벤트를 통해 직접 호출하면 차단 문제를 줄일 수 있습니다.


10. 최종 구현

이제 부모와 팝업 간의 메시지 통신과 팝업 옵션 설정을 통해 Vue.js 애플리케이션에서 팝업 창을 성공적으로 구현할 수 있습니다. 이를 통해 작업 흐름을 효율적으로 관리하고 사용자 경험을 개선할 수 있습니다.


 

 

 

728x90
728x90