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

相关推荐
mCell4 小时前
如何零成本搭建个人站点
前端·程序员·github
mCell5 小时前
为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞
前端·设计模式·agent
恋猫de小郭5 小时前
AI 在提高你工作效率的同时,也一直在增加你的疲惫和焦虑
前端·人工智能·ai编程
少云清5 小时前
【安全测试】2_客户端脚本安全测试 _XSS和CSRF
前端·xss·csrf
萧曵 丶5 小时前
Vue 中父子组件之间最常用的业务交互场景
javascript·vue.js·交互
银烛木5 小时前
黑马程序员前端h5+css3
前端·css·css3
m0_607076605 小时前
CSS3 转换,快手前端面试经验,隔壁都馋哭了
前端·面试·css3
听海边涛声5 小时前
CSS3 图片模糊处理
前端·css·css3
IT、木易5 小时前
css3 backdrop-filter 在移动端 Safari 上导致渲染性能急剧下降的优化方案有哪些?
前端·css3·safari
0思必得06 小时前
[Web自动化] Selenium无头模式
前端·爬虫·selenium·自动化·web自动化