[Vue Router warn]: Component “default“ in record with path “/xx“ is a function that does not return
[debug日记]
[Vue Router warn]: Component “default” in record with path “/xxx” is a function that does not return a Promise. If you were passing a functional component, make sure to add a “displayName” to the component. This will break in production if not fixed.
【方案一】
一种可能的解决方法是更改你的导入组件的路径。
当使用vite时,使用了一款插件dynamic-import-vars
进行动态导入有只能使用相对路径的要求。
这些限制的中文翻译如下:
限制
要知道在汇总包中注入什么,我们必须能够对代码进行一些静态分析,并对可能的导入做出一些假设。比如当你只使用一个变量,理论上您可以从整个文件系统中导入任何内容。
function importModule(path) {// 鬼知道这里会导入什么?return import(path);
}
为了帮助静态分析,并避免可能的脚枪,我们仅限于以下几条规则:
导入必须以 ./
或者 ../
开头
所有导入(import)必须使用相对被导入文件的路径。导入**不
允许以一个变量开头、使用绝对路径**,或者裸导入。
// 不允许
import(bar);
import(`${bar}.js`);
import(`/foo/${bar}.js`);
import(`some-library/${bar}.js`);
导入必须带有一个文件扩展名
一个文件夹可能包含了你不想导入的东西。 所以我们要求在静态部分的导入以一个文件扩展名来结尾。
// 不允许
import(`./foo/${bar}`);
// 允许
import(`./foo/${bar}.js`);
导入你自己的目录时必须指定一个文件名字符串模板
当你导入你的目录,你可能最终会得到你不想导入的文件,包括你自己的模块,基于这个原因要求指定一个文件名字符串模板
// 不允许
import(`./${foo}.js`);
// 允许
import(`./module-${foo}.js`);
因此,虽然你在vite配置文件vite.config.ts(或js)中配置了defineConfig中的resolve.alias
字段以指定了别名,但是由于插件只允许使用相对路径,因此导致报错。
因此改成以./
或者以../
开头的相对路径就好。
【方案二】
可以给vue-router的 component
字段返回一个 Promise并将的组件作为value传入resolve。
请返照以下思路:
{path:..., ..., component:() => Promise.resolve(your_component)}
实际上遇到这种情况时更可能是在使用一个函数导入一个异步组件,比如这样:
import { defineAsyncComponent } from "vue" const AsyncComp = defineAsyncComponent(() =>new Promise((resolve, reject) => {resolve(...)})
)
其中解决函数中可以直接指定一个描述VUE组件的对象。也可以导入,即:
const AsyncComp = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
可以打开vue router源码的类型声明文件相关部分内容:
这里默认给出的为defineAsyncComponent第一个参数loader
,就是VUE文件的路径。更详细的请自行看这部分源码了解。
function defineAsyncComponent(source) {if (shared.isFunction(source)) {source = { loader: source };}const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times outsuspensible = true, onError: userOnError } = source;let pendingRequest = null;let resolvedComp;let retries = 0;const retry = () => {retries++;pendingRequest = null;return load();};const load = () => {let thisRequest;return (pendingRequest ||(thisRequest = pendingRequest =loader().catch(err => {err = err instanceof Error ? err : new Error(String(err));if (userOnError) {return new Promise((resolve, reject) => {const userRetry = () => resolve(retry());const userFail = () => reject(err);userOnError(err, userRetry, userFail, retries + 1);});}else {throw err;}})// !!! 当 Promise 为resolve 的时候,.then((comp) => { if (thisRequest !== pendingRequest && pendingRequest) {return pendingRequest;}if (!comp) {warn(`Async component loader resolved to undefined. ` +`If you are using retry(), make sure to return its return value.`);}// interop module defaultif (comp &&(comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {comp = comp.default;}if (comp && !shared.isObject(comp) && !shared.isFunction(comp)) {throw new Error(`Invalid async component load result: ${comp}`);}resolvedComp = comp; return comp;})));};return defineComponent({name: 'AsyncComponentWrapper',__asyncLoader: load,get __asyncResolved() {return resolvedComp;},setup() {const instance = currentInstance;// already resolvedif (resolvedComp) {return () => createInnerComp(resolvedComp, instance);}const onError = (err) => {pendingRequest = null;handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);};// suspense-controlled or SSR.if ((suspensible && instance.suspense) ||(isInSSRComponentSetup)) {return load().then(comp => {return () => createInnerComp(comp, instance);}).catch(err => {onError(err);return () => errorComponent? createVNode(errorComponent, {error: err}): null;});}const loaded = reactivity.ref(false);const error = reactivity.ref();const delayed = reactivity.ref(!!delay);if (delay) {setTimeout(() => {delayed.value = false;}, delay);}if (timeout != null) {setTimeout(() => {if (!loaded.value && !error.value) {const err = new Error(`Async component timed out after ${timeout}ms.`);onError(err);error.value = err;}}, timeout);}load().then(() => {loaded.value = true;if (instance.parent && isKeepAlive(instance.parent.vnode)) {// parent is keep-alive, force update so the loaded component's// name is taken into accountqueueJob(instance.parent.update);}}).catch(err => {onError(err);error.value = err;});return () => {if (loaded.value && resolvedComp) {return createInnerComp(resolvedComp, instance);}else if (error.value && errorComponent) {return createVNode(errorComponent, {error: error.value});}else if (loadingComponent && !delayed.value) {return createVNode(loadingComponent);}};}});
}
附:标准的JavaScript动态导入是不要求相对路径的:
动态导入-摘录自MDN
标准导入语法是静态的,并且总是会在加载时评估导入模块中的所有代码。在您希望有条件地或按需加载模块的情况下,您可以改用动态导入。以下是您可能需要使用动态导入的一些原因:
- 静态导入会显着减慢代码的加载速度,并且您需要正在导入的代码的可能性很小,或者直到以后才需要它。
- 静态导入会显着增加程序的内存使用量,并且您需要导入的代码的可能性很小。
- 当您导入的模块在加载时不存在时
- 当需要动态构造导入说明符字符串时。(静态导入仅支持静态说明符。)
- 当导入的模块有副作用时,除非某些条件为真,否则您不想要这些副作用。(建议不要在模块中产生任何副作用,但有时您无法在模块依赖项中控制这一点。)
仅在必要时使用动态导入。静态形式更适合加载初始依赖项,并且可以更容易地从静态分析工具和tree shaking中受益。
要动态导入模块,import
可以将关键字作为函数调用。以这种方式使用时,它会返回一个承诺。
import('/modules/my-module.js').then((module) => {// Do something with the module.});
let module = await import('/modules/my-module.js');
[Vue Router warn]: Component “default“ in record with path “/xx“ is a function that does not return相关推荐
- 报错 Component “default“ in record with path “/“ is a Promise instead of a function that return ...
vue3+vite2 抱错 vue-router.esm-bundler.js:72 [Vue Router warn]: Component "default" in recor ...
- 已解决vue-router4路由报“[Vue Router warn]: No match found for location with path“
vue-router4动态加载的模式下,当我们在当前页面刷新浏览器时,会出现一个警告 [Vue Router warn]: No match found for location with path ...
- vue-router.esm-bundler.js6c0271 [Vue Router warn] No match found for location with path
vue-router.esm-bundler.js6c02:71 [Vue Router warn]: No match found for location with path 又是低级问题,上图 ...
- vue-router.esm-bundler.js?6c02:71 [Vue Router warn]: No match found for location with path
vue-router.esm-bundler.js?6c02:71 [Vue Router warn]: No match found for location with path 又是低级问题,上图 ...
- [Vue Router warn]: Discarded invalid param(s) “id“ when navigating. Seexxxxxxxfor more details
警告信息建议访问的链接 场景: 当我 在vue3 组合式api中尝试使用name+params去路由跳转并传递参数的时候,出现警告信息,并且接收不到params的参数.代码如下: a页面跳转b页面 / ...
- Vue Router路由守卫
全局前置.后置路由守卫 router/index.js import Vue from 'vue'; import VueRouter from 'vue-router'; import List f ...
- Vue | Vue Router 路由的使用
文章目录 一.路由的基本使用 1.创建 Vue 项目并引入 vue-router 2.编写 Components 组件 3.编写路由文件 4.在主文件 Main.js 中引入路由 5.添加 route ...
- Vue源码 Vue Router(三)matcher 路由匹配器
Vue源码 Vue Router(三)matcher Vue源码 Vue Router(三)matcher matcher createMatcher addRoutes match 总结 单步调试参 ...
- Vue Router的详细教程
Vue Router的详细教程 安装 #直接下载 / CDN https://unpkg.com/vue-router/dist/vue-router.js Unpkg.com 提供了基于 NPM 的 ...
最新文章
- 论坛报名 | 人工智能与疫情精准防控
- CMake 指定安装目录
- jboss1.7_在JBoss 7中使用HA Singleton
- mysql 索引语法_MySQL 索引:语法及案例剖析
- 【深度学习】当YOLOv5遇见OpenVINO!
- python实验三答案_20194123 实验三《Python程序设计》实验报告
- Mysql半双工主从复制
- 零基础学Java的10个方法
- 李善友:为什么外企人不敢创业
- VSCode配置PyQt5和designer
- 开发者生态与双引擎:华为的雄心壮志!
- SwiftyJSON的基本用法
- oracle获取字符的长度的函数,oracle取字符串长度的函数length()和hengthb()
- 龙芯3A3000上实现BLFS的轻量级桌面LXDE
- php远程登录linux,如何远程连接linux桌面
- 树莓派4B 编译安装rtl8192eu usb网卡驱动
- Win 7 配置FTP权限
- 两个案例带你搞定JBoss Marshalling编解码在Netty中的应用
- 2017CCPC中南地区赛暨湘潭大学邀请赛总结
- Cadence Allegro解散Group组图文教程及视频演示
热门文章
- 【Leetcode 795】Number of Subarrays with Bounded Maximum
- 【React】设计高质量的React组件
- ValueError: could not broadcast input array from shape (*,*) into shape (*)
- C# Programming Study #2
- C#通过COM组件调用IDL的pro程序
- [Ajax] 如何使用Ajax传递多个复选框的值
- 个人开发—进度记录(二)
- tesseract-ocr 识别中文扫描图片
- macosx安装之旅(1)-硬盘安装
- Mono for Android 4.2初探