vue全局trycatch

在 Vue 3 中,并没有一个原生的"全局 try...catch"语法可以直接包裹整个应用,因为 JavaScript 的 try...catch 只能捕获同步阻塞代码。

不过,为了实现类似"全局捕获所有错误"的效果,保障页面不卡顿且用户体验友好,我们需要组合使用 Vue 提供的生命周期钩子全局配置 以及原生浏览器事件

以下是实现 Vue 3 全局错误捕获的完整方案:

1. Vue 全局错误处理器 (核心)

这是 Vue 3 官方提供的兜底方案,用于捕获组件渲染、侦听器以及生命周期钩子中的未处理异常。

复制代码
// main.js 或 main.ts
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// 设置全局错误处理器
app.config.errorHandler = (err, instance, info) => {
  // err: 错误对象
  // instance: 出错的组件实例
  // info: Vue 特定的错误信息(如错误来源的生命周期钩子)
  
  console.error('Vue 全局捕获到错误:', err, info)
  
  // 这里可以进行错误上报
  // reportErrorToService(err, info)
}

app.mount('#app')

2. 捕获未处理的 Promise 异常

try...catch 无法捕获异步 Promise 中被 reject 但没有被 .catch() 的错误。我们需要监听 unhandledrejection 事件。

复制代码
// main.js 或单独的 error-handler.js
window.addEventListener('unhandledrejection', (event) => {
  console.error('未处理的 Promise 错误:', event.reason)
  
  // 阻止浏览器控制台的默认报错(可选,通常用于生产环境隐藏细节)
  // event.preventDefault();
  
  // 上报错误
  // reportError(event.reason);
});

3. 捕获静态资源与脚本错误

对于 <script> 标签加载的 JS/CSS 错误,或者图片加载失败等,需要监听 windowerror 事件。

复制代码
window.addEventListener('error', (event) => {
  // 区分是脚本错误还是资源加载错误
  if (event.target !== window) {
    // 资源加载错误 (img, script, css)
    console.error('资源加载失败:', event.target.src || event.target.href)
  } else {
    // JS 运行时错误
    console.error('JS 运行时错误:', event.error)
  }
}, true); // 使用捕获模式

4. 组合式 API 中的局部捕获 (errorCaptured)

如果你不想让某个子组件的崩溃导致整个页面挂掉,可以使用 errorCaptured 钩子(类似于 React 的 Error Boundary)。

复制代码
<script setup>
import { onErrorCaptured } from 'vue'

// 用于捕获后代组件的错误
onErrorCaptured((err, instance, info) => {
  console.error('组件边界捕获错误:', err, info)
  
  // 返回 false 阻止错误继续向上冒泡到 errorHandler
  // 返回 true 则继续冒泡
  return false 
})
</script>

5. 封装一个通用的"安全调用"函数

为了模拟对异步函数的"全局 try/catch",你可以封装一个高阶函数,自动捕获异步错误并防止崩溃。

复制代码
// utils/safeCall.js
export function safeCall(asyncFn, defaultVal = null) {
  return async (...args) => {
    try {
      return await asyncFn(...args)
    } catch (error) {
      console.error('异步函数执行出错:', error)
      // 防止抛出异常,返回默认值
      return defaultVal 
    }
  }
}

// 在组件中使用
import { safeCall } from '@/utils/safeCall'

const riskyApiCall = safeCall(async () => {
  const res = await fetch('/api/bad-endpoint')
  return res.json()
}, {}); // 如果出错,返回空对象而不是抛出异常

// 调用时无需再写 try/catch
const data = await riskyApiCall()

📌 总结:全方位防护策略

错误类型 捕获方式 适用场景
Vue 组件渲染/生命周期 app.config.errorHandler Vue 内部的运行时错误
未捕获的异步异常 window.addEventListener('unhandledrejection') async/await 未加 try/catch 的错误
JS 运行时/资源加载 window.addEventListener('error') 脚本语法错误、图片/CSS/JS 加载失败
局部组件崩溃 errorCaptured 钩子 防止某个子组件崩溃导致白屏,显示"降级 UI"

通过组合使用以上 5 种方式,你就可以在 Vue 3 项目中实现一个坚不可摧的"全局 try...catch"机制。

相关推荐
Surmon1 天前
彻底搞懂大模型 Temperature、Top-p、Top-k 的区别!
前端·人工智能
木斯佳1 天前
前端八股文面经大全:bilibili生态技术方向二面 (2026-03-25)·面经深度解析
前端·ai·ssd·sse·rag
不会写DN1 天前
Gin 日志体系详解
前端·javascript·gin
冬夜戏雪1 天前
实习面经记录(十)
java·前端·javascript
爱学习的程序媛1 天前
【Web前端】JavaScript设计模式全解析
前端·javascript·设计模式·web
小码哥_常1 天前
从SharedPreferences到DataStore:Android存储进化之路
前端
老黑1 天前
开源工具 AIDA:给 AI 辅助开发加一个数据采集层,让 AI 从错误中自动学习(Glama 3A 认证)
前端·react.js·ai·nodejs·cursor·vibe coding·claude code
薛先生_0991 天前
js学习语法第一天
开发语言·javascript·学习
jessecyj1 天前
Spring boot整合quartz方法
java·前端·spring boot
苦瓜小生1 天前
【前端】|【js手撕】经典高频面试题:手写实现function.call、apply、bind
java·前端·javascript