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

相关推荐
奔跑路上的Me2 分钟前
前端导出 Word/Excel/PDF 文件
前端·javascript
bluceli2 分钟前
JavaScript异步编程深度解析:从回调到Async Await的演进之路
前端·javascript
青青家的小灰灰13 分钟前
Vue 3 新标准:<script setup> 核心特性、宏命令与避坑指南
前端·vue.js·面试
SuperEugene14 分钟前
路由与布局骨架篇:布局系统 | 头部、侧边栏、内容区、面包屑的拆分与复用
前端·javascript·vue.js
代码煮茶15 分钟前
前端网络请求实战 | Axios 从入门到封装(拦截器 / 错误处理 / 重试)
javascript
进击的尘埃15 分钟前
组合式函数 Composables 的设计模式:如何写出可复用的 Vue3 Hooks
javascript
大金乄18 分钟前
用canvans画一个流程图
前端
大金乄21 分钟前
TreeSelect 是一个基于 Element UI 的树形选择器组件,结合了 el-select 和 el-tree 的功能,支持单选和多选模式,支持树形
前端
最强僚机斯内克22 分钟前
Vue 3 + Vite 自动引入插件完整指南(unplugin-vue-components,unplugin-auto-import)
vue.js
大金乄22 分钟前
自动构建打包脚本(开发环境)
前端