Vue组件动态导入:处理组件不存在的报错问题
Vue异步加载不存在的组件时避免报错的解决方案
问题原因
Vite在开发环境下,请求不存在的模块会返回HTML页面(而非JS模块),导致浏览器抛出MIME type mismatch错误;生产环境则直接返回404。这类网络层面的错误无法被defineAsyncComponent的errorComponent直接捕获,因为错误发生在模块加载的网络阶段,而非组件初始化阶段。
解决方案
方案1:在Loader中捕获加载错误并返回兜底组件
修改defineAsyncComponent的loader函数,通过try/catch捕获加载失败的情况,直接返回兜底组件:
<template> <component :is="Component"></component> </template> <script> import { defineAsyncComponent } from 'vue'; import ViewCommon from './ViewCommon.vue'; export default { components: { ViewCommon, }, data() { return { Component: null, } }, async created() { const compPath = `./mods/${specificApp.name}/ViewMod.vue`; this.Component = defineAsyncComponent({ loader: async () => { try { // 尝试加载定制组件 return await import(compPath); } catch (err) { // 加载失败时返回兜底组件 return { default: ViewCommon }; } }, timeout: 3000 }); }, } </script>
方案2:用Vite Glob导入预判断组件是否存在
借助Vite的import.meta.globAPI预扫描所有可能存在的定制组件,提前判断路径是否有效,避免发起无效的网络请求:
<template> <component :is="Component"></component> </template> <script> import { defineAsyncComponent } from 'vue'; import ViewCommon from './ViewCommon.vue'; // 预扫描所有mod目录下的ViewMod.vue组件,生成可访问的组件路径映射 const availableModComponents = import.meta.glob('./mods/**/ViewMod.vue'); export default { components: { ViewCommon, }, data() { return { Component: null, } }, created() { const targetCompPath = `./mods/${specificApp.name}/ViewMod.vue`; if (availableModComponents[targetCompPath]) { // 组件存在,异步加载 this.Component = defineAsyncComponent({ loader: availableModComponents[targetCompPath], timeout: 3000 }); } else { // 组件不存在,直接使用兜底组件 this.Component = ViewCommon; } }, } </script>
纠正你之前的代码错误
你之前直接使用import().catch()时,错误地调用了mod.default()——Vue组件的默认导出是组件选项对象,不是函数,正确写法应为this.Component = mod.default。不过即便修正这点,仍无法避免Vite返回HTML导致的MIME错误,因此推荐使用上述两种方案。
内容的提问来源于stack exchange,提问作者Damien Herraud
相关产品推荐
相关产品推荐

