Vue3 is 属性
is 属性是 Vue 中实现动态组件的核心属性,用于动态地指定当前元素应该渲染为哪个组件。
基本说明
is 属性主要用于动态组件场景,允许在运行时根据数据动态切换不同的组件进行渲染。这是 Vue 中实现动态组件功能的主要方式。
- 类型: String | Component
- 作用: 动态切换组件,实现组件的复用与动态渲染。
基本用法
1、动态切换组件
使用 <component> 元素配合 is 属性可以实现动态组件:
实例
<template>
<div>
<!-- currentComponent 可以是 'ComponentA'、'ComponentB' 等字符串 -->
<component :is="currentComponent"></component>
<button @click="toggleComponent">切换组件</button>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
data() {
return {
currentComponent: 'ComponentA'
}
},
components: {
ComponentA,
ComponentB
},
methods: {
toggleComponent() {
this.currentComponent = this.currentComponent === 'ComponentA'
? 'ComponentB'
: 'ComponentA'
}
}
}
</script>
<div>
<!-- currentComponent 可以是 'ComponentA'、'ComponentB' 等字符串 -->
<component :is="currentComponent"></component>
<button @click="toggleComponent">切换组件</button>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
data() {
return {
currentComponent: 'ComponentA'
}
},
components: {
ComponentA,
ComponentB
},
methods: {
toggleComponent() {
this.currentComponent = this.currentComponent === 'ComponentA'
? 'ComponentB'
: 'ComponentA'
}
}
}
</script>
2、使用组件对象
is 的值也可以直接是组件对象:
实例
<template>
<div>
<component :is="currentComponent"></component>
<button @click="switchToA">显示 A</button>
<button @click="switchToB">显示 B</button>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
data() {
return {
currentComponent: ComponentA
}
},
methods: {
switchToA() {
this.currentComponent = ComponentA
},
switchToB() {
this.currentComponent = ComponentB
}
}
}
</script>
<div>
<component :is="currentComponent"></component>
<button @click="switchToA">显示 A</button>
<button @click="switchToB">显示 B</button>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
data() {
return {
currentComponent: ComponentA
}
},
methods: {
switchToA() {
this.currentComponent = ComponentA
},
switchToB() {
this.currentComponent = ComponentB
}
}
}
</script>
使用场景
1、标签切换
实现类似标签页切换的效果:
实例
<template>
<div>
<!-- 标签导航 -->
<button
v-for="tab in tabs"
:key="tab.name"
:class="{ active: currentTab === tab.name }"
@click="currentTab = tab.name"
>
{{ tab.label }}
</button>
<!-- 动态组件 -->
<component :is="currentTabComponent" />
</div>
</template>
<script>
import HomeTab from './tabs/HomeTab.vue'
import ProfileTab from './tabs/ProfileTab.vue'
import SettingsTab from './tabs/SettingsTab.vue'
export default {
data() {
return {
currentTab: 'Home',
tabs: [
{ name: 'Home', label: '首页', component: HomeTab },
{ name: 'Profile', label: '个人资料', component: ProfileTab },
{ name: 'Settings', label: '设置', component: SettingsTab }
]
}
},
computed: {
currentTabComponent() {
const tab = this.tabs.find(t => t.name === this.currentTab)
return tab ? tab.component : null
}
}
}
</script>
<div>
<!-- 标签导航 -->
<button
v-for="tab in tabs"
:key="tab.name"
:class="{ active: currentTab === tab.name }"
@click="currentTab = tab.name"
>
{{ tab.label }}
</button>
<!-- 动态组件 -->
<component :is="currentTabComponent" />
</div>
</template>
<script>
import HomeTab from './tabs/HomeTab.vue'
import ProfileTab from './tabs/ProfileTab.vue'
import SettingsTab from './tabs/SettingsTab.vue'
export default {
data() {
return {
currentTab: 'Home',
tabs: [
{ name: 'Home', label: '首页', component: HomeTab },
{ name: 'Profile', label: '个人资料', component: ProfileTab },
{ name: 'Settings', label: '设置', component: SettingsTab }
]
}
},
computed: {
currentTabComponent() {
const tab = this.tabs.find(t => t.name === this.currentTab)
return tab ? tab.component : null
}
}
}
</script>
2、条件渲染不同组件
根据条件动态选择要渲染的组件:
实例
<template>
<div>
<select v-model="selectedType">
<option value="warning">警告</option>
<option value="error">错误</option>
<option value="success">成功</option>
</select>
<component :is="alertComponent" :message="message" />
</div>
</template>
<script>
import WarningAlert from './WarningAlert.vue'
import ErrorAlert from './ErrorAlert.vue'
import SuccessAlert from './SuccessAlert.vue'
export default {
data() {
return {
selectedType: 'warning',
message: '这是一条提示消息'
}
},
computed: {
alertComponent() {
const componentMap = {
warning: WarningAlert,
error: ErrorAlert,
success: SuccessAlert
}
return componentMap[this.selectedType]
}
}
}
</script>
<div>
<select v-model="selectedType">
<option value="warning">警告</option>
<option value="error">错误</option>
<option value="success">成功</option>
</select>
<component :is="alertComponent" :message="message" />
</div>
</template>
<script>
import WarningAlert from './WarningAlert.vue'
import ErrorAlert from './ErrorAlert.vue'
import SuccessAlert from './SuccessAlert.vue'
export default {
data() {
return {
selectedType: 'warning',
message: '这是一条提示消息'
}
},
computed: {
alertComponent() {
const componentMap = {
warning: WarningAlert,
error: ErrorAlert,
success: SuccessAlert
}
return componentMap[this.selectedType]
}
}
}
</script>
在原生元素上使用 is
在 Vue 3.1+ 中,当 is 属性用于原生 HTML 元素时,它会被解释为原生 Web 平台的自定义元素功能。
但有时需要在 DOM 模板中将原生元素替换为 Vue 组件。例如在 <table> 中使用自定义组件作为行:
实例
<table>
<tbody>
<tr is="vue:my-row-component"></tr>
</tbody>
</table>
<tbody>
<tr is="vue:my-row-component"></tr>
</tbody>
</table>
使用 vue: 前缀可以让 Vue 将该元素渲染为 Vue 组件而不是原生 HTML 元素。
注意事项
is 属性的值:可以是组件的名称字符串,也可以是组件对象。当使用字符串时,组件名称应该与注册的组件名一致。
使用计算属性:可以根据复杂的条件逻辑返回不同的组件,实现更灵活的动态组件切换。
keep-alive 缓存动态组件
使用 <keep-alive> 包装动态组件,可以缓存组件实例,避免每次切换时重新创建:
实例
<template>
<div>
<button @click="currentTab = 'home'">首页</button>
<button @click="currentTab = 'profile'">个人资料</button>
<keep-alive>
<component :is="currentTabComponent" />
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
currentTab: 'home'
}
},
computed: {
currentTabComponent() {
return this.currentTab + '-tab'
}
}
}
</script>
<div>
<button @click="currentTab = 'home'">首页</button>
<button @click="currentTab = 'profile'">个人资料</button>
<keep-alive>
<component :is="currentTabComponent" />
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
currentTab: 'home'
}
},
computed: {
currentTabComponent() {
return this.currentTab + '-tab'
}
}
}
</script>
<keep-alive> 会缓存切换过的组件实例,当组件再次显示时,会直接从缓存中恢复,而不是重新创建。

Vue3 内置属性