文章目录
- 一、使用 v-if 和 v-else 实现组件切换
- 二、:is 实现组件切换
- 两种方式的对比
一、使用 v-if 和 v-else 实现组件切换
<template><div><!-- 切换按钮 --><button @click="showComponentA = !showComponentA">切换组件(当前:{{ showComponentA ? 'A' : 'B' }})</button><!-- 组件切换区域 --><component-a v-if="showComponentA"></component-a><component-b v-else></component-b></div>
</template><script>
// 子组件 A
Vue.component('component-a', {template: '<div style="color: blue">组件 A 内容</div>'
})// 子组件 B
Vue.component('component-b', {template: '<div style="color: green">组件 B 内容</div>'
})export default {data() {return {showComponentA: true // 控制显示状态的布尔值}}
}
</script>
代码解析:
-
组件定义:
- 使用
Vue.component
全局注册了两个组件component-a
和component-b
- 每个组件有简单的模板内容和不同的样式
- 使用
-
切换逻辑:
- 通过
showComponentA
布尔值数据属性控制显示状态 v-if="showComponentA"
当值为 true 时显示组件 Av-else
会自动对应前一个v-if
,当值为 false 时显示组件 B
- 通过
-
切换按钮:
- 点击按钮时通过
@click="showComponentA = !showComponentA"
反转布尔值 - 按钮文字会动态显示当前展示的组件
- 点击按钮时通过
效果说明:
- 初始状态显示蓝色文字的 “组件 A 内容”
- 点击按钮后:
- 切换为绿色文字的 “组件 B 内容”
- 按钮文字变为 “切换组件(当前:B)”
- 再次点击切回组件 A
注意事项:
v-else
必须紧跟在带v-if
的元素之后- 使用
v-if
会触发组件的销毁/重建,如果需要保持组件状态,可以用<keep-alive>
包裹 - 如果要处理多个条件,可以使用
v-else-if
扩展:保持组件状态
<keep-alive><component-a v-if="showComponentA"></component-a><component-b v-else></component-b>
</keep-alive>
使用 <keep-alive>
后,组件切换时不会销毁实例,会保留组件状态(如表单输入内容等)。
二、:is 实现组件切换
在 Vue2 中通过 :is
属性绑定实现组件切换是更灵活的动态组件用法,特别适合需要动态切换不同组件或实现类似标签页功能的场景。
基础示例:动态组件切换
<template><div><!-- 切换按钮 --><button @click="currentComponent = 'ComponentA'">显示 A</button><button @click="currentComponent = 'ComponentB'">显示 B</button><!-- 动态组件容器 --><component :is="currentComponent"></component></div>
</template><script>
// 定义组件选项对象
const ComponentA = { template: '<div style="color: blue">组件 A</div>' }
const ComponentB = { template: '<div style="color: green">组件 B</div>' }export default {data() {return {currentComponent: 'ComponentA' // 控制当前显示的组件}},components: {ComponentA, // 局部注册组件ComponentB}
}
</script>
核心机制解析
- 动态组件标签:
<component>
是 Vue 内置的特殊组件,通过:is
属性动态决定渲染哪个组件
<component :is="currentComponent"></component>
- 组件绑定方式:
- 字符串形式:直接使用注册的组件名(需全局/局部注册)
- 对象形式:可以直接绑定组件选项对象(无需注册)
<!-- 直接绑定组件对象 --><component :is="componentObj"></component>
- 组件切换逻辑:
通过修改currentComponent
的值即可实现组件切换,比v-if
/v-else
更灵活,尤其适合多组件切换
高级用法:配合 keep-alive
<keep-alive><component :is="currentComponent"></component>
</keep-alive>
- 作用:缓存非活动组件实例,避免重复销毁/创建
- 典型场景:需要保留组件状态(如表单输入内容、滚动位置等)
组件映射表模式
<template><div><button v-for="(comp, name) in componentMap" :key="name"@click="currentComponent = comp">显示 {{ name }}</button><component :is="currentComponent"></component></div>
</template><script>
const ComponentA = { template: '<div>组件 A</div>' }
const ComponentB = { template: '<div>组件 B</div>' }export default {data() {return {currentComponent: null,componentMap: {'A': ComponentA,'B': ComponentB}}}
}
</script>
- 优势:通过对象映射管理组件,更易于扩展
两种方式的对比
特性 | :is 动态组件 | v-if /v-else |
---|---|---|
适用场景 | 多组件切换/动态组件名 | 简单的二元条件切换 |
组件实例生命周期 | 默认销毁重建(可用 keep-alive) | 触发销毁/重建 |
代码简洁度 | 多组件时更简洁 | 适合少量组件 |
灵活性 | 可通过变量动态指定任意组件 | 需要显式编写条件分支 |
实际应用场景
- 标签页切换(Tabs 组件)
- 动态表单(根据类型切换不同输入组件)
- 可视化搭建平台(动态渲染组件库中的组件)
- 权限控制(根据不同权限显示不同组件)
注意事项
- 组件必须已经注册(全局或局部)
- 组件名大小写敏感(推荐始终使用大驼峰)
- 动态切换组件时,可以通过
key
属性强制重新创建实例:
<component :is="currentComponent" :key="reloadKey"></component><!-- 修改 reloadKey 强制刷新 -->