如何在Quasar QDialog中按Esc键时根据条件拦截关闭操作
解决方案:利用
before-hide事件拦截并控制关闭流程 Quasar的QDialog提供的before-hide事件可拦截对话框关闭操作,回调中返回false就能阻止默认关闭行为,结合这个特性可以实现需求:
- 保留
QDialog的默认Esc关闭行为(无需添加no-esc-dismiss),同时绑定before-hide事件 - 在回调中判断是否存在未保存修改:
- 无修改:返回
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事件,可采用以下方式:
- 给
QDialog添加no-esc-dismiss禁用默认Esc关闭逻辑 - 组件挂载时监听全局
keydown事件捕获Esc键 - 组件卸载时移除事件监听避免内存泄漏
代码示例:
<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
相关产品推荐
相关产品推荐

