본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Modal

원문 보기 위키 갱신

현재 화면 위에 뜨는 모달 대화상자 컴포넌트예요.

출처: 문서

본문

언제 사용하나요

  1. 사용자가 무언가를 처리해야 하지만 페이지를 이동해 작업 흐름을 끊고 싶지 않을 때, Modal을 사용해 현재 화면 한가운데에 레이어를 띄우고 해당 작업을 진행할 수 있어요.

  2. Modal은 사용자와 상호작용하는 역할을 해요. 사용자는 Modal 안에서 정보를 입력하거나 안내를 읽고, 옵션을 설정하는 등의 작업을 할 수 있어요.

기본 사용법

:::demo v-model 양방향 바인딩으로 Modal 표시 여부를 제어하고, title 속성으로 Modal 제목을 설정해요.

<template>
  <d-button @click="handleClick">打开 modal</d-button>
  <d-modal v-model="visible" title="Start Snapshot Version">
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
  </d-modal>
</template>

<script>
import { defineComponent, ref, reactive } from 'vue';

export default defineComponent({
  setup() {
    const visible = ref(false);
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = () => {
      visible.value = true;
    };

    return { visible, data, handleClick };
  },
});
</script>

:::

마지막 닫힘 위치 유지

:::demo keep-last를 사용하면 modal을 다시 열 때 마지막에 닫았던 위치가 그대로 유지돼요.

<template>
  <d-button @click="handleClick">打开 modal</d-button>
  <d-modal v-model="visible" title="Start Keep Last" :keep-last="true">
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
  </d-modal>
</template>

<script>
import { defineComponent, ref, reactive } from 'vue';

export default defineComponent({
  setup() {
    const visible = ref(false);
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = () => {
      visible.value = true;
    };

    return { visible, data, handleClick };
  },
});
</script>

:::

제목과 동작 버튼 커스터마이즈

:::demo header 슬롯으로 Modal 상단 영역을 커스터마이즈할 수 있어요. 하위 컴포넌트 d-modal-header가 상단 영역에 기본 스타일을 제공하며, 하위 컴포넌트에 style/class를 지정해 스타일을 바꿀 수 있어요. footer 슬롯도 마찬가지예요.

<template>
  <d-button @click="handleClick">打开 modal</d-button>
  <d-modal v-model="visible">
    <template #header>
      <d-modal-header>
        <d-icon name="like"></d-icon>
        <span>Good Title</span>
      </d-modal-header>
    </template>
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
    <template #footer>
      <d-modal-footer style="text-align: right; padding-right: 20px;">
        <d-button @click="hidden">取消</d-button>
        <d-button @click="hidden">确认</d-button>
      </d-modal-footer>
    </template>
  </d-modal>
</template>
<script>
import { ref, defineComponent, reactive } from 'vue';
export default defineComponent({
  setup() {
    const visible = ref(false);
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = () => {
      visible.value = true;
    };
    const hidden = () => {
      visible.value = false;
    };

    return { visible, data, handleClick, hidden };
  },
});
</script>

:::

정보 알림

:::demo 여러 타입의 정보 알림 모달이에요.

<template>
  <d-button class="mr-1" @click="handleClick('success')">success</d-button>
  <d-button class="mr-1" @click="handleClick('failed')">failed</d-button>
  <d-button class="mr-1" @click="handleClick('warning')">warning</d-button>
  <d-button class="mr-1" @click="handleClick('info')">info</d-button>
  <d-modal v-model="visible" title="Start Snapshot Version" :type="type">
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
  </d-modal>
</template>

<script>
import { defineComponent, ref, reactive } from 'vue';

export default defineComponent({
  setup() {
    const visible = ref(false);
    const type = ref('');
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = (t) => {
      visible.value = true;
      type.value = t;
    };

    return { visible, data, handleClick, type };
  },
});
</script>

:::

닫기 전 콜백

:::demo 사용자가 닫기 버튼이나 오버레이를 클릭하면 before-close가 호출돼요. 비동기 작업을 마친 뒤 done 파라미터로 Modal을 닫을 수 있어요. close는 Modal이 닫힐 때 발생해요.

<template>
  <d-button @click="handleClick">打开 modal</d-button>
  <d-modal v-model="visible" :before-close="beforeClose" @close="handleClose" style="width: 500px;">
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
    <template #footer>
      <d-modal-footer style="text-align: right; padding-right: 20px;">
        <d-button @click="hidden">取消</d-button>
        <d-button @click="hidden">确认</d-button>
      </d-modal-footer>
    </template>
  </d-modal>
</template>

<script>
import { ref, defineComponent, reactive } from 'vue';

export default defineComponent({
  setup() {
    const visible = ref(false);
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = () => {
      visible.value = true;
    };
    const hidden = () => {
      visible.value = false;
    };
    const beforeClose = (done) => {
      new Promise((resolve) => {
        setTimeout(resolve, 1000);
      }).then(done);
    };
    const handleClose = () => {
      console.log("Modal关闭")
    }

    return { visible, data, handleClick, hidden, beforeClose, handleClose };
  },
});
</script>

:::

모달 안 버튼에 autofocus로 자동 포커스 주기

::: demo button에 autofocus를 설정하면 자동으로 포커스를 받고, enter 키로 버튼 클릭을 트리거할 수 있어요.

<template>
  <d-button @click="handleClick">打开 modal</d-button>
  <d-modal v-model="visible" title="Start Snapshot Version">
    <div>name: {{ data.name }}</div>
    <div>age: {{ data.age }}</div>
    <div>address: {{ data.address }}</div>
    <template #footer>
      <d-modal-footer style="text-align: right; padding-right: 20px;">
        <d-button @click="hidden" autofocus>取消</d-button>
        <d-button @click="hidden">确认</d-button>
      </d-modal-footer>
    </template>
  </d-modal>
</template>

<script>
import { defineComponent, ref, reactive } from 'vue';
export default defineComponent({
  setup() {
    const visible = ref(false);
    const data = reactive({
      name: 'Tom',
      age: 20,
      address: 'Chengdu',
    });
    const handleClick = () => {
      visible.value = true;
    };
    const hidden = () => {
      visible.value = false;
    };
    return { visible, data, handleClick, hidden };
  },
});
</script>

:::

파라미터 타입 기본값 설명 Demo 링크
v-model boolean false Modal 표시 여부 기본 사용법
title string - 선택, Modal 제목 기본 사용법
keep-last boolean false 선택, 이전 이동 위치 유지 여부 마지막 닫힘 위치 유지
lock-scroll boolean true 선택, body 스크롤 잠금 여부
close-on-click-overlay boolean true 선택, 빈 곳 클릭으로 Modal 닫기 가능 여부
before-close (done) => void - 선택, 닫기 전 콜백. done을 호출하면 Modal 닫기 가능 닫기 전 콜백
escapable boolean true 선택, esc 키로 팝업 닫기 지원 여부
show-close boolean true 선택, 닫기 버튼 표시 여부
draggable boolean true 선택, 다이얼로그 드래그 가능 여부
show-animation boolean true 선택, 애니메이션 표시 여부
show-overlay boolean true 선택, 오버레이 레이어 표시 여부
append-to-body boolean true 선택, Modal을 body 레이어로 승격 여부
type success | failed | warning | info - 선택, 다이얼로그 힌트 메시지
이벤트명 타입 설명
close - Modal 닫힐 때 트리거
슬롯명 설명
default Modal 콘텐츠
header Modal 상단 커스텀. title과 header를 함께 사용하면 header 우선 렌더링
footer Modal 하단 커스텀

더 알아보기 (Learn more)

before-close 콜백과 header/footer 슬롯을 활용하면 실제 서비스에 필요한 모달을 쉽게 만들 수 있어요.