深入解析 <component :is> 在 Vue3 组合式中的使用与局限

1.问题

说明:在 Vue3 中使用组合式 API 时,动态组件通过 is 属性渲染可能会遇到组件未正确显示的问题。实际写法如下所示:我的目的就是遍历数组顶部组件,里面有个type就是对应的is属性(因为数据放置在数据库,属性值是字符串,不是组件对象)。它渲染出了dom节点就是没有展示。

javascript 复制代码
<script setup>
   import DashBoardHeader from './dash-board-header/index.vue'
</script>
      <component
          v-for="(item,index) in dashBoardHeaderAll.dashBoardHeader"
          :key="index"
          :is="item.type"
          :universalStyle="dashBoardHeaderAll.dashBoardHeaderUniversalStyle"
          :getData="item.data"
          :getTitle="item.title"
          :getStyle="item.style"
          :param="item.param"
          :unit="item.unit"
      ></component>

2.分析

说明:Vue 3 组合式传字符串只会匹配全局注册,不会自动匹配局部注册组件名。官网写法如下,也就是component的值是个组件对象,而不是字符串。

3.解决

说明:我们通过字段映射的方式,让它的属性值变成组件对象。或者注册成全局组件。或者改成选项式写法。

javascript 复制代码
<script setup>
import DashBoardHeader from './dash-board-header/index.vue'


const componentsMap = {
  DashBoardHeader: DashBoardHeader
}
</script>


         <component
          v-for="(item,index) in dashBoardHeaderAll.dashBoardHeader"
          :key="index"
           :is="componentsMap[item.type]"
          :universalStyle="dashBoardHeaderAll.dashBoardHeaderUniversalStyle"
          :getData="item.data"
          :getTitle="item.title"
          :getStyle="item.style"
          :param="item.param"
          :unit="item.unit"
      ></component>

4.结论

  • Vue 2:如果传字符串,会先查找当前组件的局部注册,匹配到就用;找不到再查全局注册。

  • Vue 3 选项式 API:为了兼容 Vue 2,传字符串依然会匹配局部注册组件名。

  • Vue 3 组合式 API(<script setup>):如果传字符串,只会去查全局注册组件名,不会匹配局部注册名;要让它工作,需要传组件对象变量,或者在模板中通过映射把字符串转成组件对象。