在 Vue 2 中,动态组件是一种强大的特性,允许你在同一个位置切换不同的组件。
1、基本概念
动态组件通过特殊的 <component>
标签和 is
属性来实现。is
的值可以是:
- 组件名称(注册的组件 ID)
- 组件选项对象
当 is
的值变化时,Vue 会自动切换到对应的组件。
<template>
<div>
<!-- 标签页导航 -->
<div class="tabs">
<button @click="currentTab = 'Home'">Home</button>
<button @click="currentTab = 'Posts'">Posts</button>
<button @click="currentTab = 'Archive'">Archive</button>
</div>
<!-- 动态组件区域 -->
<component :is="currentTab"></component>
</div>
</template>
<script>
// 导入组件
import Home from './components/Home.vue';
import Posts from './components/Posts.vue';
import Archive from './components/Archive.vue';
export default {
data() {
return {
currentTab: 'Home', // 当前激活的组件名
};
},
components: {
Home,
Posts,
Archive,
},
};
</script>
2、动态切换组件选项对象
除了组件名称,is
也可以直接绑定组件选项对象:
<template>
<component :is="currentComponent"></component>
</template>
<script>
export default {
data() {
return {
currentComponent: null,
};
},
created() {
// 动态创建组件选项
this.currentComponent = {
template: '<div>动态创建的组件</div>',
};
},
};
</script>
3、组件缓存
1)当切换动态组件时,默认会销毁之前的组件。如果需要保留组件状态,可以使用 <keep-alive>
包裹:
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
2)<keep-alive>
的 include
和 exclude
属性用于精确控制哪些组件需要被缓存,哪些不需要。这两个属性可以帮助优化应用性能,避免不必要的组件缓存
2.1)include/exclude
- 作用:缓存/排除 名称匹配的组件。
- 值类型:字符串、正则表达式或数组。
<!-- 缓存 name 为 "ComponentA" 和 "ComponentB" 的组件 -->
<keep-alive include="ComponentA,ComponentB">
<router-view />
</keep-alive>
<!-- 使用数组语法 -->
<keep-alive include="['ComponentA', 'ComponentB']">
<router-view />
</keep-alive>
<!-- 使用正则表达式(需用 v-bind) -->
<keep-alive :include="/^Component[A-B]$/">
<router-view />
</keep-alive>
2.2)组件命名规则
1.组件选项中的 name:
export default {
name: 'MyComponent', // 必须显式声明 name
// ...
}
2.全局注册的组件:使用注册时的名称。
Vue.component('GlobalComponent', {
// ...
});
3.未命名组件:
无法被 include/exclude 匹配,因此不会被缓存。
2.3)
优先级:exclude
的优先级高于 include
。若同时存在,exclude
中的组件将被忽略
4、生命周期钩子
1)基本概念
-
<keep-alive>
是 Vue 的内置组件,用于缓存被包裹的组件实例,避免重复创建和销毁,提高性能。当组件在<keep-alive>
内被切换时,不会触发普通的生命周期钩子(如created
、mounted
),而是触发专门的缓存生命周期钩子: activated()
:组件被激活(插入 DOM)时调用。deactivated()
:组件被停用时(从 DOM 移除)调用。
export default {
activated() {
// 组件被激活时执行(缓存状态下)
},
deactivated() {
// 组件被停用时执行(缓存状态下)
},
};
2) 使用场景
2.1 数据缓存与刷新
当组件被缓存时,其状态会被保留。使用 activated()
可以在每次组件显示时刷新数据:
export default {
data() {
return {
list: []
}
},
activated() {
// 每次组件显示时重新获取数据(即使被缓存)
this.fetchData();
},
methods: {
fetchData() {
// API请求...
}
}
}
2.2 定时器 / 监听器管理
在 activated()
中创建监听或定时器,在 deactivated()
中销毁,避免内存泄漏:
export default {
activated() {
// 组件激活时监听滚动事件
window.addEventListener('scroll', this.handleScroll);
},
deactivated() {
// 组件停用时移除监听
window.removeEventListener('scroll', this.handleScroll);
}
}
5、动态组件与路由的区别
特性 | 动态组件 | Vue Router |
---|---|---|
切换方式 | 通过 is 属性手动控制 | 通过 URL 路径自动切换 |
状态保留 | 需配合 <keep-alive> | 自动保留(根据路由配置) |
应用场景 | 同一页面内的组件切换 | 完整的单页应用路由系统 |
注意事项
- 确保所有可能的组件都已在父组件中注册。
- 使用
<keep-alive>
会缓存组件实例,可能占用更多内存。 - 动态组件切换会触发组件的销毁和重建(除非使用
<keep-alive>
)。