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

Vue3中onBeforeRouteLeave无法等待用户输入的解决问询

解决方案

你的问题核心有两个:一是组合式API中错误使用了this,二是用轮询监听用户输入的方式不可靠且无效。以下是修正后的完整实现:

1. 修正响应式变量与模板逻辑

首先确保所有弹窗相关变量都是ref声明的响应式变量,同时修改按钮点击事件,直接关联Promise的状态变更:

模板部分

<q-dialog v-model="unsaveGridDialog" persistent>
    <q-card>
        <q-card-section class="row items-center">
            <q-avatar icon="save" color="primary" text-color="white" />
            <span class="q-ml-sm">是否要在未保存网格的情况下离开页面?</span>
        </q-card-section>

        <q-card-actions align="right">
            <q-btn @click="handleCancel" flat label="取消" color="primary" v-close-popup />
            <q-btn @click="handleConfirm" flat label="确认离开" color="primary" v-close-popup />
        </q-card-actions>
    </q-card>
</q-dialog>

2. 重构脚本逻辑

响应式变量声明

import { ref, onBeforeRouteLeave } from 'vue';

const unsaveGridDialog = ref(false);
// 保存Promise的resolve/reject引用,由按钮点击触发状态变更
let resolveLeavePromise = null;
let rejectLeavePromise = null;
// 假设这是你判断是否有未保存更改的变量
const hasUnsavedChanges = ref(false);

弹窗与路由守卫逻辑

function showUnsaveDialog() {
    unsaveGridDialog.value = true;
    return new Promise((resolve, reject) => {
        resolveLeavePromise = resolve;
        rejectLeavePromise = reject;
    });
}

function handleConfirm() {
    resolveLeavePromise?.();
    resetDialogState();
}

function handleCancel() {
    rejectLeavePromise?.();
    resetDialogState();
}

function resetDialogState() {
    unsaveGridDialog.value = false;
    resolveLeavePromise = null;
    rejectLeavePromise = null;
}

// 路由守卫
onBeforeRouteLeave((to, from, next) => {
    if (hasUnsavedChanges.value) {
        showUnsaveDialog()
            .then(() => next()) // 用户确认,允许路由跳转
            .catch(() => next(false)); // 用户取消,阻止路由跳转
    } else {
        next(); // 无未保存更改,直接跳转
    }
});

问题原理解释

  1. this的错误使用:在Vue3组合式API中,this指向undefined,你原来的this.unsaveConfirm无法获取到响应式变量的值,导致轮询永远不会触发resolve或reject。
  2. 轮询的低效与不可靠:通过setTimeout轮询监听变量状态是不必要的,直接通过用户点击事件触发Promise状态变更才是正确的异步交互方式。
  3. 状态重置:每次弹窗关闭后重置Promise引用,避免后续弹窗出现逻辑混乱。

内容的提问来源于stack exchange,提问作者Tadeas Vasko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 16:27:37