雙層彈框 - daniel-qa/Vue GitHub Wiki
- 正確做法是:
你必須在按下第一層的「我已確認」按鈕時,呼叫 Promise 的 resolve()。
✅ 解法:把 langDialogHandlers 加回來!
const langDialogHandlers = ref({
onConfirm: () => {},
onCancel: () => {}
});
然後更新你 < el-dialog> 裡按鈕的事件:
<el-button type="danger" @click="langDialogHandlers.value.onConfirm()">
我已確認,繼續發送
</el-button>
<el-button @click="langDialogHandlers.value.onCancel()">取消</el-button>
✅ 並在 waitForLangConfirm() 中註冊 handlers:
function waitForLangConfirm() {
return new Promise((resolve, reject) => {
sendLangDialogVisible.value = true; // 叫出彈框
langDialogHandlers.value = {
onConfirm: () => {
sendLangDialogVisible.value = false;
resolve(); // 👈 關鍵!才能讓 await 繼續執行
},
onCancel: () => {
sendLangDialogVisible.value = false;
reject(); // 👈 取消時觸發 catch 區塊
}
};
});
}
- 最外層的呼叫
try {
await waitForLangConfirm(); // 等使用者操作
// 👇 使用者按「確認」,會從 resolve() 繼續往下走
debugger;
console.log("使用者確認了,開始發送");
// 最後一次提醒 (多語系才檢查)
try {
await ElMessageBox.confirm(
'最後確認,是否進行訊息發送',
'提示',
{ type: 'error', confirmButtonText: '確定', cancelButtonText: '取消' }
);
} catch {
// 使用者取消
return;
}
} catch {
// 👇 使用者按「取消」,會從 reject() 進來這裡
console.log("使用者取消了發送");
return; //返回
}
<template>
<div style="padding: 20px">
<el-button type="primary" @click="handleSend">送出</el-button>
<!-- 第一道自訂確認 Dialog -->
<el-dialog v-model="langDialogVisible" title="語系訊息提醒" width="400">
<p>此為語系訊息,可能產生較高費用。</p>
<p style="color: #e6a23c;">請再次確認是否要發送?</p>
<template #footer>
<el-button @click="cancelLangConfirm">取消</el-button>
<el-button type="primary" @click="confirmLangConfirm">我已確認</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus'
// 狀態
const langDialogVisible = ref(false)
let langDialogHandlers = {
onConfirm: () => { },
onCancel: () => { },
}
// 顯示第一層自訂 Dialog,回傳 Promise
function waitForLangConfirm() {
return new Promise((resolve, reject) => {
langDialogVisible.value = true // 這個會打開彈窗
// 由於有 promise,會等到觸發函式時,才進行處理,不然會一直等待
langDialogHandlers = {
onConfirm: () => {
langDialogVisible.value = false
resolve()
},
onCancel: () => {
langDialogVisible.value = false
reject('使用者取消第一層')
},
}
})
}
// Dialog 裡面的事件綁定
function confirmLangConfirm() {
langDialogHandlers.onConfirm()
}
function cancelLangConfirm() {
langDialogHandlers.onCancel()
}
// 主流程:雙重確認
async function handleSend() {
try {
await waitForLangConfirm()
await ElMessageBox.confirm(
'此為最終確認,確定要送出嗎?',
'發送確認',
{
type: 'warning',
confirmButtonText: '確定發送',
cancelButtonText: '取消',
}
)
ElMessage.success('✅ 已送出!')
} catch (err) {
ElMessage.info('❌ 發送已取消')
}
}
</script>