Vue Composition API使用:is属性条件渲染组件不生效问题
问题根源
<script setup> 语法糖的编译机制下,模板中直接写标签名能正常渲染组件,是因为编译阶段会自动把标签名和你手动导入、或全局注册的组件变量做映射绑定。但你把组件名以字符串形式传给:is属性时,运行阶段Vue无法将字符串和实际导入的组件对象建立关联,只会把它识别为普通的自定义HTML标签,因此渲染出来是空标签,没有组件实际内容。
修复方法
不要传字符串给动态组件的:is属性,直接将导入的组件引用存入步骤数组即可,同时可以简化模板逻辑,不需要遍历所有页面再通过v-if筛选当前页,直接根据当前步骤索引取对应组件渲染,性能更好。
完整修正代码
<script setup> import MLandingPage from "~~/components/onboarding/MLandingPage.vue"; import MFirstName from "~/components/onboarding/MFirstName.vue"; import MWelcome from "~/components/onboarding/MWelcome.vue"; import MLastName from "~/components/onboarding/MLastName.vue"; import MAge from "~/components/onboarding/MAge.vue"; import { ref } from "vue"; // 直接存储组件引用,不需要转为字符串,组件本身不需要响应式 const onboardingPages = [MLandingPage, MFirstName, MWelcome, MLastName, MAge]; const onboardingStep = ref(0); function prevStep() { // 增加边界判断,避免步骤索引小于0 if (onboardingStep.value > 0) { onboardingStep.value -= 1; } } function nextStep() { // 增加边界判断,避免步骤索引超出总页数 if (onboardingStep.value < onboardingPages.length - 1) { onboardingStep.value += 1; } } </script> <template> <div class="flex items-center justify-end gap-2 md:gap-10 mt-16 px-5 md:px-20"> <h1>Example Page Title</h1> <div class="mt-16 p-5 pr-8 md:px-20 md:mt-24"> <!-- 直接渲染当前步骤对应组件,无需遍历所有页面 --> <component :is="onboardingPages[onboardingStep]" /> </div> <button @click="prevStep" :disabled="onboardingStep === 0">Back</button> <button @click="nextStep" :disabled="onboardingStep === onboardingPages.length - 1">Next</button> </div> </template>
补充说明
- 后续新增引导步骤时,只需按顺序导入对应组件,加入
onboardingPages数组即可,不需要修改其他逻辑。 - 给前进后退按钮增加
disabled状态,能在第一步/最后一步时阻止无效点击,提升交互体验。 - 直接传组件引用时,不需要手动处理组件名的大小写格式转换,Vue会自动完成渲染适配。
内容的提问来源于stack exchange,提问作者maisiemay06
相关产品推荐
相关产品推荐

