基于URL参数动态导入Vue组件



我正试图根据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个问题。。。

  1. 你的"一网打尽";路由被定义为CCD_ 7,因此如果你导航到URL CCD_;对象";部分匹配并且CCD_ 9参数将是包含单个项目"的数组;动作";。因此created钩子将弹出此单个项目,params数组保持为空,componentPath也将为空(这是Cannot find module './.vue'错误的原因(

  2. 在Vue3中,不赞成使用旧的异步组件语法(() => import(``./${path}.vue``)(。在创建异步组件时,您应该始终使用defineAsyncComponent助手(这就是Invalid VNode type: undefinedVue警告的原因(

所以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>

最新更新