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"机制。

相关推荐
yingyima4 分钟前
Unix 时间戳转换实战:一次差点毁掉项目的低级错误
前端
盼兮29 分钟前
用AI编程从零搭建一个响应式数据看板
前端·人工智能·数据可视化
Lan.W30 分钟前
vue3-element-admin里新增mock接口一直没有生成,不生效
前端·javascript·vue.js·mock
小满zs32 分钟前
Next.js部署(Vercel)
前端·next.js
仙古.梦回~35 分钟前
vue-skills
前端·javascript·vue.js
倒霉熊dd1 小时前
Python 学习(第二部分:函数、模块与面向对象编程)
前端·数据库·python
gCode Teacher 格码致知1 小时前
Javascrip提高:CSS backdrop-filter的使用方法-由Deepseek产生
前端·css
gCode Teacher 格码致知1 小时前
Javascript提高:canvas画布的网格背景-由Deepseek产生
javascript·css·css3
清灵xmf1 小时前
JS 原生深拷贝的终极方案——structuredClone
前端·javascript·vue.js·json.stringify·structuredclone
前端 贾公子1 小时前
响应式系统基础:依赖追踪的基础 —— 发布订阅模式(前端应用最广的设计模式)上
javascript·vue.js