利用动态组件可以动态切换页面中显示的组件。使用<component>标签可以定义动态组件,语法格式如下。
<component is="要渲染的组件"></component>
上述语法格式中,<component>标签必须配合is属性一起使用,is属性的属性值表示要渲染的组件,当该属性值发生变化时,页面中渲染的组件也会发生变化。
is属性的属性值可以是字符串或组件,当属性值为组件时,如果要实现组件的切换,需要调用shallowRef()函数定义响应式数据,将组件保存为响应式数据。shallowRef()函数只处理对象最外层属性的响应,它比ref()函数更适合于将组件保存为响应式数据。
演示动态组件的使用方法
创建src\components\MyLeft.vue文件。
<template>MyLeft组件</template>
创建src\components\MyRight.vue文件。
<template>MyRight组件</template>
创建src\components\DynamicComponent.vue文件,在该文件中导入并使用MyLeft和MyRight组件,实现单击按钮时动态切换组件的效果。
<template>
<button @click="showComponent = MyLeft">展示MyLeft组件</button>
<button @click="showComponent = MyRight">展示MyRight组件</button>
<div><component :is="showComponent"></component></div>
</template>
<script setup >
import MyLeft from './MyLeft.vue'
import MyRight from './MyRight.vue'
import { shallowRef } from 'vue'
const showComponent = shallowRef(MyLeft)
</script>
为什么要使用组件缓存?
使用动态组件实现组件之间的按需切换时,隐藏的组件会被销毁,展示出来的组件会被重新创建。因此,当一个组件被销毁后又重新创建时,组件无法保持销毁前的状态。
如果在多个组件之间进行动态切换时想要保持这些组件的状态,以及避免重复渲染导致的性能问题,可以通过组件缓存来实现。
组件缓存可以使组件创建一次后,不会被销毁。在Vue中可以通过KeepAlive组件来实现组件缓存。
KeepAlive组件可通过<KeepAlive>标签来定义,定义时使用<KeepAlive>标签包裹需要被缓存的组件。<KeepAlive>标签的语法格式如下。
<KeepAlive>
被缓存的组件
</KeepAlive>
演示KeepAlive组件的使用
编写src\components\MyLeft.vue文件,这一步先不使用KeepAlive组件,观察动态组件被销毁的过程。
<template>
MyLeft组件
<div>
count值为: {{ count }}
<button @click="count++">+1</button>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const count = ref(0)
onMounted(() => {
console.log('MyLeft组件被挂载了')
})
onUnmounted(() => {
console.log('MyLeft组件被销毁了')
})
</script>
保存上述代码后,在浏览器中访问http://127.0.0.1:5173/,单击“+1”按钮后的页面效果和控制台
修改src\components\DynamicComponent.vue文件,添加<KeepAlive>标签将实现组件缓存。
<div>
<KeepAlive>
<component :is="showComponent"></component>
</KeepAlive>
</div>
为什么需要设置组件缓存相关的生命周期函数?
在Vue开发中,有时需要在组件被激活或者被缓存时执行某些操作。为此,Vue提供了组件缓存相关的生命周期函数,可以监听组件被激活和组件被缓存的事件。
当组件被激活时,会触发组件的onActivated()生命周期函数;当组件被缓存时,会触发组件的onDeactivated()生命周期函数。这两个生命周期函数的语法格式如下。
// onActivated()生命周期函数
onActivated(() => { })
// onDeactivated()生命周期函数
onDeactivated(() => { })
演示组件缓存相关的生命周期函数的使用
修改 src\components\MyLeft.vue文件,在<script>标签中定义onActivated()和onDeactivated()生命周期函数。
<script setup>
import { ref, onMounted, onUnmounted, onActivated, onDeactivated } from 'vue'
onActivated(() => {
console.log('MyLeft组件被激活了')
})
onDeactivated(() => {
console.log('MyLeft组件被缓存了')
})
</script>
修改src\components\MyRight.vue文件,在<script>标签中定义onActivated()和onDeactivated()生命周期函数。
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
console.log('MyRight组件被激活了')
})
onDeactivated(() => {
console.log('MyRight组件被缓存了')
})
</script>
在默认情况下,所有被<KeepAlive>标签包裹的组件都会被缓存。如果想要实现特定组件被缓存或者特定组件不被缓存的效果,可以通过KeepAlive组件的常用属性include、exclude属性来实现。
KeepAlive组件的常用属性如下表所示。
属性 | 类型 | 说明 |
include | 字符串或正则表达式 | 只有名称匹配的组件会被缓存 |
exclude | 字符串或正则表达式 | 名称匹配的组件不会被缓存 |
max | 数字 | 最多可以缓存组件实例个数 |
在<KeepAlive>标签中使用include属性和exclude属性时,多个组件名之间使用英文逗号分隔。
以include属性为例,语法格式如下。
<KeepAlive include="组件名1, 组件名2">
被缓存的组件
</KeepAlive>
注意:
在使用KeepAlive组件对名称匹配的组件进行缓存时,它会根据组件的name选项进行匹配。如果没有使用setup语法糖,必须手动声明name选项;如果使用了setup语法糖,Vue会根据文件名自动生成name选项,无须手动声明name选项。例如,在MyLeft.vue文件中使用setup语法糖时,自动生成的组件名为MyLeft。
在非setup语法糖的<script>标签中定义name选项的示例代码如下。
<script>
export default {
name: 'MyComponent'
}
</script>
演示KeepAlive组件的include属性的使用方法。
修改 src\components\DynamicComponent.vue组件中的代码,实现只缓存MyLeft组件。
<KeepAlive include="MyLeft">
<component :is="showComponent"></component>
</KeepAlive>