uni-app showModal和redirectTo一起用会报错

uni-app showModal和redirectTo一起用会报错

开发环境 版本号 项目创建方式
Mac 15.6.1 (24G90) HBuilderX

示例代码:

const handleClose = () => {  
    uni.showModal({  
        title: ' 退出提示',  
        content: '是否保存本次记录?',  
        cancelText: '不保存',  
        confirmText: '保存',  
        confirmColor: theme.primary as string,  
        complete: (res) => {  
            setTimeout(() => {  
                if (res.confirm) {  
                    saveCbtRecordStore().then(() => {  
                        uni.redirectTo({  
                            url: '/pages/cbt/list'  
                        })  
                    })  
                } else {  
                    uni.redirectTo({  
                        url: '/pages/index/index'  
                    })  
                }  
            }, 100)  
        }  
    })  
}

操作步骤:

将上述代码中的300改成100就出错,设置成300以上就不会出错。

预期结果:

在 complete 中redirectTo不报错。

实际结果:

Uncaught TypeError: Cannot read properties of null (reading '$pageLayoutInstance')  
    at Module.closeDialogPage (uni-h5.es.js:8537:53)  
    at uni-h5.es.js:30005:13

更多关于uni-app showModal和redirectTo一起用会报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

找到 HBuilderX 或者 cli 依赖路径,解压我提供的压缩包进行替换即可。
HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-h5/dist-x

提供复现工程。我使用 HBuilderX4.81 + vue3+ uniapp + chrome 运行下面代码表现正常,正常跳转,控制台无报错
<template>
<view>
<button @click=“handleClose”>go</button>
</view>
</template>

<script setup lang="ts"> const handleClose = () => { uni.showModal({ title: ' 退出提示', content: '是否保存本次记录?', cancelText: '不保存', confirmText: '保存', complete: (res) => { uni.redirectTo({ url: '/pages/me/me' }) } }) } </script>

更多关于uni-app showModal和redirectTo一起用会报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


你是 uniappx 是吧?x-web 复现了此问题,后续提 bug 请明确 uniapp x

这是一个典型的异步时序问题。在H5环境下,showModal弹窗关闭和页面跳转存在执行时序冲突。

setTimeout延迟时间过短(如100ms)时,redirectTo页面跳转操作会在弹窗完全关闭前执行,导致框架在清理弹窗DOM时无法正确获取页面布局实例,从而抛出$pageLayoutInstance为null的错误。

解决方案:

  1. 移除setTimeout - 直接在complete回调中执行跳转:
complete: (res) => {
    if (res.confirm) {
        saveCbtRecordStore().then(() => {
            uni.redirectTo({ url: '/pages/cbt/list' })
        })
    } else {
        uni.redirectTo({ url: '/pages/index/index' })
    }
}
  1. 使用showModal的success回调替代complete:
success: (res) => {
    if (res.confirm) {
        saveCbtRecordStore().then(() => {
            uni.redirectTo({ url: '/pages/cbt/list' })
        })
    } else {
        uni.redirectTo({ url: '/pages/index/index' })
    }
}
回到顶部