我正试图根据url参数中输入的路径导入一个vue组件。例如,如果在浏览器中输入<host>/<path>
,我想导入位于<path>.vue
的vue组件。
在我的routes.js
文件中,我有一个将获得嵌套路径的路由:
{ path: 'object/:catchAll(.*)*', component: BaseObject }
并发送到BaseObject
:
<template>
<div>
<component :is="componentFile" />
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
name: 'BaseObject',
data () {
return {
componentPath: '',
address: ''
}
},
methods: {
importComponent (path) {
return () => import(`./${path}.vue`)
}
},
computed: {
componentFile () {
return this.importComponent(this.componentPath)
}
},
created () {
const params = this.$route.params.catchAll
console.log(params)
this.address = params.pop()
this.componentPath = params.join('/')
}
}
</script>
当我导航到http://localhost:8080/#/object/action
时,我希望加载位于./action.vue
的组件。但这并没有发生——相反,我得到了以下错误:
runtime-core.esm-bundler.js?9e79:38 [Vue warn]: Invalid VNode type: undefined (undefined)
at <Anonymous>
at <BaseObject onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > >
at <RouterView>
at <QPageContainer>
at <QLayout view="lHh Lpr lFf" >
at <MainLayout onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy {$i18n: {…}, $t: ƒ, …} > >
at <RouterView>
at <App>
和
Uncaught (in promise) Error: Cannot find module './.vue'
at app.js:416
有人知道如何做到这一点吗?
您的代码至少有2个问题。。。
-
你的"一网打尽";路由被定义为CCD_ 7,因此如果你导航到URL CCD_;对象";部分匹配并且CCD_ 9参数将是包含单个项目"的数组;动作";。因此
created
钩子将弹出此单个项目,params
数组保持为空,componentPath
也将为空(这是Cannot find module './.vue'
错误的原因( -
在Vue3中,不赞成使用旧的异步组件语法(
() => import(``./${path}.vue``)
(。在创建异步组件时,您应该始终使用defineAsyncComponent
助手(这就是Invalid VNode type: undefined
Vue警告的原因(
所以BaseObject
应该是这样的:
<template>
<div>
<component :is="componentFile" />
</div>
</template>
<script>
import { defineComponent, defineAsyncComponent } from "vue";
export default defineComponent({
name: "BaseObject",
data() {
return {
componentPath: "",
address: "",
};
},
methods: {},
computed: {
componentFile() {
return defineAsyncComponent(() =>
import(`../components/${this.componentPath}.vue`)
);
},
},
created() {
const params = this.$route.params.catchAll;
console.log(this.$route.params);
// this.address = params.pop();
this.componentPath = params.join("/");
},
});
</script>
工作演示
还要注意,定义";"一网打尽";这样的路由是危险的,因为它将匹配所有路由,如-/object/action
、/object/action/dd
、/object/action/dd/bb
等,而这些组件将不存在。所以,也许只允许一个级别的嵌套会更好。。。
我猜您正在使用Webpack捆绑应用程序并解析JS模块。正如您在文档中看到的https://webpack.js.org/api/module-methods/#import-1,import()
返回一个promise,它是异步工作的。在使用组件之前,您必须首先解决该承诺。
methods: {
async getComponentFile() {
const component = await this.importComponent(this.componentPath);
return component;
}
},
不要硬求简单的解决方案!
<component :is="componentFile" />
export default {
name: 'BaseObject',
components: {
firstComponent: () => import('...'),
secondComponent: () => import('...'),
thirdComponent: () => import('...')
}
computed: {
componentFile () {
return this.detectComponentBasedPath()
}
},
methods: {
detectComponentBasedPath () {
...
}
}
}
</script>