vue.js - 基于 URL 参数动态导入 Vue 组件
问题描述
我正在尝试根据输入 url 参数的路径导入 vue 组件。因此,例如,如果<host>/<path>
在浏览器中输入,我想导入一个位于<path>.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
有谁知道如何做到这一点?
解决方案
您的代码至少有两个问题...
您的“catch all”路由被定义为
{ path: 'object/:catchAll(.*)*', component: BaseObject }
,如果您导航到 URLhttp://localhost:8080/#/object/action
,则匹配“object”部分,catchAll
param 将是一个包含单个项目“action”的数组。所以created
钩子会弹出这个单项,params
数组保持为空并且componentPath
也将是空的(这是Cannot find module './.vue'
错误的原因)在 Vue 3 中,旧的异步组件语法 (
() => import(``./${path}.vue``)
)已弃用。创建异步组件时应始终使用defineAsyncComponent
helper(这是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>
另请注意,像这样定义“catch all”路线是危险的,因为它会将所有路线匹配为 - /object/action
、等/object/action/dd
,/object/action/dd/bb
并且这些组件将不存在。所以也许只允许一层嵌套会更好......
推荐阅读
- php - 如果产品描述为空,WooCommerce 如何隐藏“描述”选项卡
- javascript - Axios 是否支持与原生 fetch() 相同的“keepalive”功能?
- android - 与正确显示文本的虚拟设备相比,为什么我的文本在 Google 商店中消失了?
- python - 使用python解析getEmailActivityUserDetail报告
- spring - 如何跟踪 WebClient POST/GET 请求的进度 - Spring Boot?
- reactjs - Is there a way to force tab unmount in ChakraUI tabs component?
- jira - 在现有 Confluence 应用程序中更改指向 Jira OAuth 的链接
- node.js - 使用“纱线”运行命令但没有它的情况下出现纱线问题
- c++ - 为什么我的程序从 csv 文件 c++ 输出特殊字符
- php - 需要凭据 php twilio