使用vue3-sfc-loader加载SFC时出现异步组件加载器未处理错误
使用vue3-sfc-loader加载SFC时的异步组件错误警告解决
问题现象
使用vue3-sfc-loader加载单文件组件(SFC)时,出现Vue警告:
[Vue warn]: Unhandled error during execution of async component loader at <AsyncComponentWrapper> at <App>
即使注释掉路由相关代码,警告仍存在。已确认.vue文件能成功加载,Promise也返回了组件内容。此前在Vue 2中使用httpvueloader无问题,当前未使用Node.js,完全依赖vue3-sfc-loader,实现方式参考官方文档。
用户代码
<div id="app"> <h1>Hello App!</h1> <helloworld></helloworld> <p> <router-link to="/">Go to Home</router-link> <router-link to="/about">Go to About</router-link> <router-link to="/about/1234">Go to About/1234</router-link> </p> <router-view></router-view> </div> <script> const { loadModule } = window['vue3-sfc-loader']; const Home = { template: '<div>Home</div>' }; const About = { template: '<div>About</div>', created() { console.debug("About created"); this.$watch( () => this.$route.params, (toParams, previousParams) => { // react to route changes... console.debug(toParams, previousParams); } ) } } const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/about/:userId', component: About } ]; const options = { moduleCache: { vue: Vue, }, getFile(filepath) { fetch(filepath).then(res => { if ( !res.ok ) throw Object.assign(new Error(res.statusText + ' ' + filepath), { res }); return { getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text(), } }); }, addStyle(textContent) { console.debug(textContent); const style = Object.assign(document.createElement('style'), { textContent }); const ref = document.head.getElementsByTagName('style')[0] || null; document.head.insertBefore(style, ref); }, } const router = VueRouter.createRouter({ history: VueRouter.createWebHashHistory(), routes, // short for `routes: routes` }); const app = Vue.createApp({ router: router, components: { 'helloworld': Vue.defineAsyncComponent(() => loadModule('/real-estate/vues/helloworld.vue', options)), }, data(){ return { } }, async mounted(){ }, methods: { }, filters: { } }).use(router).mount('#app'); </script>
问题原因
options中的getFile方法未返回fetch的Promise。vue3-sfc-loader要求getFile必须返回一个Promise来处理文件加载的异步流程,原代码中fetch(filepath).then(...)没有添加return,导致getFile返回undefined,破坏了异步加载链,触发未处理错误警告。
解决方案
1. 修复getFile方法
给fetch调用添加return,确保返回Promise:
getFile(filepath) { return fetch(filepath).then(res => { if ( !res.ok ) throw Object.assign(new Error(res.statusText + ' ' + filepath), { res }); return { getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text(), } }); }
2. 给异步组件添加错误捕获(可选)
为了更友好地处理加载错误,可以给异步组件配置错误组件:
'helloworld': Vue.defineAsyncComponent({ loader: () => loadModule('/real-estate/vues/helloworld.vue', options), errorComponent: { template: '<div>组件加载失败,请稍后重试</div>' } }),
内容的提问来源于stack exchange,提问作者Mark Speener
相关产品推荐
相关产品推荐

