Vue3(Quasar)中使用Composition API实现动态组件失败求助
Vue3(Quasar)Setup语法糖中动态组件无法渲染问题
可正常运行的Options API代码
<template> <p> <button @click="component = 'ComponentA'">Comp A</button> <button @click="component = 'ComponentB'">Comp B</button> </p> <component :is="component" /> </template> <script> import ComponentA from "../components/ComponentA.vue"; import ComponentB from "../components/ComponentB.vue"; export default { components: { ComponentA, ComponentB, }, data() { return { component: "ComponentA", }; }, }; </script>
无法正常工作的Setup语法糖代码
<template> <q-page class="flex column flex-center background-white"> <q-btn @click="component = 'ComponentA'" >ComponentA</q-btn > <q-btn @click="component = 'ComponentB'" >ComponentB</q-btn > <component :is="component" /> </q-page> </template> <script setup> import { ref, defineAsyncComponent } from "vue"; const component = ref("ComponentA"); const ComponentA = defineAsyncComponent(() => import("../components/ComponentA.vue") ); const ComponentB = defineAsyncComponent(() => import("../components/ComponentB.vue") ); </script>
问题原因
在Setup语法糖中,局部声明的组件不会自动注册为模板可通过字符串名称访问的组件。而Options API里的components选项会把组件注册到当前实例,因此可以用字符串名称引用组件;你现在直接把字符串'ComponentA'绑定到:is上,模板无法找到对应的组件引用,导致渲染失败。
两种解决方案
方案1:直接绑定组件引用
将ref的初始值和点击事件的赋值改为组件本身的引用:
<template> <q-page class="flex column flex-center background-white"> <q-btn @click="component = ComponentA">ComponentA</q-btn> <q-btn @click="component = ComponentB">ComponentB</q-btn> <component :is="component" /> </q-page> </template> <script setup> import { ref, defineAsyncComponent } from "vue"; const ComponentA = defineAsyncComponent(() => import("../components/ComponentA.vue") ); const ComponentB = defineAsyncComponent(() => import("../components/ComponentB.vue") ); // 直接将ref初始化为组件引用 const component = ref(ComponentA); </script>
方案2:创建组件映射表
如果希望保留字符串名称的使用方式,可以创建映射表,将字符串对应到组件引用:
<template> <q-page class="flex column flex-center background-white"> <q-btn @click="component = 'ComponentA'">ComponentA</q-btn> <q-btn @click="component = 'ComponentB'">ComponentB</q-btn> <!-- 通过映射表获取组件引用 --> <component :is="componentMap[component]" /> </q-page> </template> <script setup> import { ref, defineAsyncComponent } from "vue"; const component = ref("ComponentA"); const ComponentA = defineAsyncComponent(() => import("../components/ComponentA.vue") ); const ComponentB = defineAsyncComponent(() => import("../components/ComponentB.vue") ); // 创建字符串到组件的映射表 const componentMap = { ComponentA, ComponentB }; </script>
内容的提问来源于stack exchange,提问作者acroscene
相关产品推荐
相关产品推荐

