Vue 3 动态组件 component is

FreeGuideOnline 最新 2026-07-06
```

传递属性与事件

动态组件可以像普通组件一样接收 props 和监听事件。直接将它们写在 <component> 上即可,这些属性和事件会被传递给当前渲染的实际组件。

<template>
  <component 
    :is="current"
    :title="dynamicTitle"
    @custom-event="handleEvent"
  />
</template>

<script setup>
import { ref } from 'vue'
const dynamicTitle = ref('Hello')
const handleEvent = (payload) => {
  console.log('收到事件', payload)
}
</script>

如果多个动态组件的 props 结构不同,可以结合 v-bind 动态传入一个 props 对象,但要注意避免向不需要某些属性的组件传递未声明的 prop,这虽然不会报错,但会出现在组件的根元素上。可以在子组件中通过 inheritAttrs: false 或仅传递当前组件需要的属性来优化。

实际案例:标签页切换

下面是一个完整的多标签页示例,综合了动态组件、KeepAlive、异步加载和事件处理。

<template>
  <div class="tab-container">
    <nav>
      <button
        v-for="tab in tabs"
        :key="tab.name"
        :class="{ active: currentTab === tab.component }"
        @click="currentTab = tab.component"
      >
        {{ tab.label }}
      </button>
    </nav>
    <KeepAlive>
      <component
        :is="currentTab"
        :user="userInfo"
        @update="handleUpdate"
      />
    </KeepAlive>
  </div>
</template>

<script setup>
import { ref, shallowRef } from 'vue'
import Profile from './Profile.vue'
import Settings from './Settings.vue'
import AsyncReports from './AsyncReports.vue'

const tabs = [
  { name: 'profile', label: '个人信息', component: Profile },
  { name: 'settings', label: '设置', component: Settings },
  { name: 'reports', label: '报告', component: AsyncReports } // 异步组件
]

const currentTab = shallowRef(Profile) // 使用 shallowRef 避免不必要的响应式转换
const userInfo = ref({ name: '张三', role: 'user' })

function handleUpdate(data) {
  console.log('组件更新事件', data)
}
</script>