Vue3 script setup中如何使用<component :is>实现动态组件切换
核心问题根因
script setup 模式不具备普通组合式API写法中 components 配置项的隐式字符串组件映射能力:普通写法下在components中注册的组件,会被Vue自动建立「组件名字符串 → 组件对象」的索引,因此传字符串给<component :is>可以正常匹配到对应组件。但script setup仅支持直接在模板中使用导入的组件,不会自动生成上述字符串映射关系,传字符串值给:is时会因找不到对应组件引用直接失效。
可落地的调整方案
根据现有业务逻辑的差异,有两种无需修改导航栏组件原有逻辑的适配方式:
方案1:手动维护字符串-组件映射表(完全兼容原有传值逻辑)
保留原有通过字符串切换tab的逻辑,仅新增字符串与组件对象的映射关系,将模板中动态组件的取值改为从映射表匹配,完整可运行代码如下:
<template> <NavigationBar @switchTab="changeTab" :activeTab="tab" /> <!-- 从映射表中匹配对应组件对象 --> <component :is="componentMap[tab]" /> </template> <script setup> import NavigationBar from './components/NavigationBar.vue' import TemplateSyntax from './components/TemplateSyntax.vue' import DataPropsAndMethods from './components/DataPropsAndMethods.vue' import { ref } from 'vue' // 手动维护字符串值与对应组件的映射关系 const componentMap = { DataPropsAndMethods, TemplateSyntax } const tab = ref('DataPropsAndMethods') function changeTab (newTab) { tab.value = newTab } </script>
方案2:动态组件直接存储组件对象
如果导航栏触发事件时可直接传递组件引用,无需依赖字符串值匹配,可直接将ref的存储值从字符串替换为组件对象,省去映射表的维护成本:
<template> <NavigationBar @switchTab="changeTab" :activeTab="tab" /> <!-- :is直接接收组件对象即可 --> <component :is="tab" /> </template> <script setup> import NavigationBar from './components/NavigationBar.vue' import TemplateSyntax from './components/TemplateSyntax.vue' import DataPropsAndMethods from './components/DataPropsAndMethods.vue' import { ref } from 'vue' // ref直接存储组件对象,而非字符串值 const tab = ref(DataPropsAndMethods) function changeTab (newTabComponent) { tab.value = newTabComponent } </script>
注意事项
script setup中所有动态组件的匹配都需要显式提供组件引用,不要依赖全局组件注册或模板自动解析的隐式映射逻辑,避免运行时找不到组件导致的渲染空白问题。- 早期实验版的
script setup语法与正式版存在少量行为差异,升级到Vue 3正式版本后,上述两种方案均为官方推荐的标准实现方式。
内容的提问来源于stack exchange,提问作者wittgenstein
相关产品推荐
相关产品推荐

