You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Quasar QDialog中按Esc键时根据条件拦截关闭操作

解决方案:利用before-hide事件拦截并控制关闭流程

Quasar的QDialog提供的before-hide事件可拦截对话框关闭操作,回调中返回false就能阻止默认关闭行为,结合这个特性可以实现需求:

  1. 保留QDialog的默认Esc关闭行为(无需添加no-esc-dismiss),同时绑定before-hide事件
  2. 在回调中判断是否存在未保存修改:
    • 无修改:返回true允许对话框关闭
    • 有修改:弹出确认对话框,返回false阻止当前关闭;用户确认后再手动关闭原对话框

代码示例:

<template>
  <q-dialog
    v-model="showDialog"
    no-backdrop-dismiss
    @before-hide="handleBeforeHide"
  >
    <!-- 对话框内容示例 -->
    <q-input v-model="formData.name" label="名称" />
  </q-dialog>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { Dialog } from 'quasar';

const showDialog = ref(true);
const originalFormData = { name: '初始名称' };
const formData = ref({ ...originalFormData });

// 判断是否存在未保存修改
const hasUnsavedChanges = () => {
  return JSON.stringify(formData.value) !== JSON.stringify(originalFormData);
};

const handleBeforeHide = () => {
  if (!hasUnsavedChanges()) {
    return true; // 无修改,允许直接关闭
  }

  // 有修改时弹出确认框
  Dialog.create({
    title: '未保存的修改',
    message: '你有未保存的修改,确定要放弃吗?',
    ok: '放弃修改',
    cancel: true
  })
    .onOk(() => {
      showDialog.value = false; // 用户确认后手动关闭对话框
    })
    .onCancel(() => {
      // 用户取消,保持原对话框打开
    });

  return false; // 阻止当前默认关闭行为
};
</script>

备选方案:手动监听Esc键

如果偏好完全接管Esc事件,可采用以下方式:

  1. 给QDialog添加no-esc-dismiss禁用默认Esc关闭逻辑
  2. 组件挂载时监听全局keydown事件捕获Esc键
  3. 组件卸载时移除事件监听避免内存泄漏

代码示例:

<template>
  <q-dialog
    v-model="showDialog"
    no-backdrop-dismiss
    no-esc-dismiss
  >
    <!-- 对话框内容示例 -->
    <q-input v-model="formData.name" label="名称" />
  </q-dialog>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { Dialog } from 'quasar';

const showDialog = ref(true);
const originalFormData = { name: '初始名称' };
const formData = ref({ ...originalFormData });

const hasUnsavedChanges = () => {
  return JSON.stringify(formData.value) !== JSON.stringify(originalFormData);
};

const handleEscKey = (e: KeyboardEvent) => {
  if (e.key === 'Escape' && showDialog.value) {
    e.preventDefault();
    if (!hasUnsavedChanges()) {
      showDialog.value = false;
      return;
    }

    Dialog.create({
      title: '未保存的修改',
      message: '你有未保存的修改,确定要放弃吗?',
      ok: '放弃修改',
      cancel: true
    })
      .onOk(() => {
        showDialog.value = false;
      });
  }
};

onMounted(() => {
  window.addEventListener('keydown', handleEscKey);
});

onUnmounted(() => {
  window.removeEventListener('keydown', handleEscKey);
});
</script>

之前方法失效原因

  • 使用@escape-key事件时,Quasar触发该事件后仍会执行默认关闭逻辑,无法通过回调中断
  • 若before-hide事件参数为undefined,可能是版本差异,但回调返回false阻止关闭的逻辑是通用的

内容的提问来源于stack exchange,提问作者Alexander Pacha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:32:01