본문 바로가기

카테고리 없음

ref로 제어하는 커스텀 다이얼로그 만들기 (Framework7 + TailwindCSS)

반응형

🔧 ref로 제어하는 커스텀 다이얼로그 만들기 (Framework7 + TailwindCSS)

이번에는 <f7-popup>을 활용한 커스텀 다이얼로그를 직접 만들고, ref를 통해 프로그래밍적으로 제어할 수 있도록 구성해봅시다.


✅ 구현 목표

  • 다이얼로그의 열기/닫기 기능을 ref로 제어
  • title, message, confirmText, cancelText를 동적으로 전달
  • onConfirm, onCancel 같은 이벤트 핸들러도 동적으로 바인딩

🧱 Step 1. CustomDialog.vue 컴포넌트 구현

<script setup>
import { ref, reactive, defineExpose } from 'vue'

const opened = ref(false)

const state = reactive({
  title: '알림',
  message: '',
  confirmText: '확인',
  cancelText: '취소',
  onConfirm: null,
  onCancel: null,
})

function open(options = {}) {
  Object.assign(state, {
    ...options,
    onConfirm: options.onConfirm || null,
    onCancel: options.onCancel || null,
  })
  opened.value = true
}

function close() {
  opened.value = false
}

function handleConfirm() {
  state.onConfirm?.()
  close()
}

function handleCancel() {
  state.onCancel?.()
  close()
}

defineExpose({ open, close })
</script>

<template>
  <f7-popup v-model:opened="opened" class="rounded-2xl overflow-hidden">
    <f7-page class="bg-white flex flex-col items-center justify-center p-6 h-full">
      <div class="w-full max-w-sm text-center">
        <h2 class="text-xl font-bold mb-2 text-gray-900">{{ state.title }}</h2>
        <p class="text-sm text-gray-600 mb-6">{{ state.message }}</p>
        <div class="flex justify-center gap-4">
          <f7-button
            fill
            class="bg-gray-300 text-gray-800 font-medium px-4 py-2 rounded-lg"
            @click="handleCancel"
          >
            {{ state.cancelText }}
          </f7-button>
          <f7-button
            fill
            class="bg-blue-500 text-white font-medium px-4 py-2 rounded-lg"
            @click="handleConfirm"
          >
            {{ state.confirmText }}
          </f7-button>
        </div>
      </div>
    </f7-page>
  </f7-popup>
</template>

⚙️ Step 2. 사용하는 쪽에서 ref로 다이얼로그 호출

<script setup>
import { ref } from 'vue'
import CustomDialog from '@/components/CustomDialog.vue'

const alert_modal = ref()

function showDeleteConfirm() {
  alert_modal.value?.open({
    title: '삭제 확인',
    message: '정말 이 항목을 삭제하시겠습니까?',
    confirmText: '삭제',
    cancelText: '취소',
    onConfirm: () => {
      console.log('✅ 삭제됨!')
      // 실제 삭제 로직 추가
    },
    onCancel: () => {
      console.log('❎ 취소됨!')
    },
  })
}
</script>

<template>
  <f7-page>
    <f7-button @click="showDeleteConfirm">다이얼로그 열기</f7-button>
    <CustomDialog ref="alert_modal" />
  </f7-page>
</template>

🧠 팁 & 확장 방향

  • type: 'danger' 같은 속성을 추가해 버튼 색상 조건부 처리 가능
  • icon, loading, disableConfirm 등의 기능도 쉽게 확장 가능
  • 반복적인 다이얼로그 사용을 컴포넌트 하나로 통일 가능

ref를 활용한 다이얼로그 제어는 실무에서 매우 유용한 패턴입니다. 특히 Framework7처럼 컴포넌트 기반 UI 프레임워크에서는 defineExpose()와 reactive()를 적절히 사용하면 높은 유연성과 재사용성을 확보할 수 있습니다.

TailwindCSS로 디자인까지 자유롭게 컨트롤할 수 있으니, 이제 여러분의 앱에 맞게 확장해보세요!

반응형