vue3动态组件及组件缓存的使用(setup函数和setup语法糖两版)
一、动态组件
- 动态组件可通过v-if或v-show控制显示隐藏,在此不做演示;
- 动态组件可通过
component
标签中的is属性
控制; - 具体写法:
<component :is="组件名"></component>
常规写法
<template>
<div class="box">
<leOne></leOne>
<leTwo></leTwo>
</div>
</template>
<script setup>
// 引入组件
import leOne from "@/components/leOne.vue";
import leTwo from "@/components/leTwo.vue";
</script>
<style scoped lang="scss"></style>
使用动态组件
<template>
<div class="box">
<component :is="leOne"></component>
<component :is="leTwo"></component>
</div>
</template>
<script setup>
// 引入组件
import leOne from "@/components/leOne.vue";
import leTwo from "@/components/leTwo.vue";
</script>
<style scoped lang="scss"></style>
动态组件进阶写法
setup函数版本
<template>
<div class="box">
<div class="tab">
// 通过事件控制组件名称,是否创建组件
<div v-for="item, index in units"
@click="changeTap(index)"
:class="{ activeBgc: i == index }">
切换{{ item }}
</div>
</div>
<component :is="units[i]"></component>
</div>
</template>
<script>
// 引入
import { reactive, toRefs } from 'vue';
// 引入组件
import leOne from "@/components/leOne.vue";
import leTwo from "@/components/leTwo.vue";
export default {
name: 'AboutView',
// 注册组件
components: {
leOne,
leTwo
},
setup() {
const data = reactive({
units: ['leOne', 'leTwo'],
i: 0
})
// tap变动
function changeTap(index) {
data.i = index
}
return {
...toRefs(data),
changeTap
}
},
}
</script>
<style scoped lang="scss">
.activeBgc {
background-color: pink;
}
</style>
setup语法糖版本
- 通过
markRaw()
实现动态渲染组件
<template>
<div class="box">
<div class="tab">
<div v-for="item, index in units"
@click="changeTap(index)"
:class="{ activeBgc: i == index }">
切换{{ item.name }}
</div>
</div>
<component :is="units[i].comName"></component>
</div>
</template>
<script setup>
// 引入
import { reactive, toRefs, markRaw } from 'vue';
// 引入组件
import leOne from "@/components/leOne.vue";
import leTwo from "@/components/leTwo.vue";
// markRaw()标记一个对象,使其永远不会再成为响应式对象
// 在动态渲染组件的时候我们就可以使用 markRaw 包裹。
const data = reactive({
units: [
{
name: "leOne",
comName: markRaw(leOne)
},
{
name: "leTwo",
comName: markRaw(leTwo)
}
],
i: 0
})
// tap变动
function changeTap(index) {
data.i = index
}
// 解构数据
const { units, i } = toRefs(data)
</script>
<style scoped lang="scss">
.activeBgc {
background-color: pink;
}
</style>
二、缓存组件
keep-alive
是vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM;keep-alive
有以下几个属性:
1、 include
: 只有名称匹配的组件会被缓存 (支持字符串或正则表达);
2、 exclude
: 任何名称匹配的组件都不会被缓存(支持字符串或正则表达);
3、 max
:最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁
include和exclude
<KeepAlive>
默认会缓存内部的所有组件实例,但我们可以通过 include
和 exclude
来定制该行为。这两个属性的值可以是一个以英文逗号分隔的字符串或一个正则表达式,或是包含这两种类型的一个数组:
<!-- 以英文逗号分隔的字符串 -->
<keep-alive include="leOne,leTwo">
<component :is="units[i].comName"></component>
</keep-alive>
<!-- 正则表达式 (需使用 `v-bind`) -->
<keep-alive :include="/leOne|leTwo/">
<component :is="units[i].comName"></component>
</keep-alive>
<!-- 数组 (需使用 `v-bind`) -->
<KeepAlive :include="['leOne', 'leTwo']">
<component :is="units[i].comName" />
</KeepAlive>
注意:
- 它会根据组件的name选项进行匹配,所以组件如果想要条件性地被
KeepAlive
缓存,就必须显式声明一个name
选项 - 使用
<script setup>
的单文件组件会自动根据文件名生成对应的name
选项,无需再手动声明
max
- 可以通过传入
max
来限制可被缓存的最大组件实例数。 <KeepAlive>
在指定了max
后类似一个 LRU 缓存:如果缓存的实例数量即将超过指定的那个最大数量,则最久没有被访问的缓存实例将被销毁,以便为新的实例腾出空间。
<KeepAlive :max="10">
<component :is="units[i].comName" />
</KeepAlive>
缓存组件的生命周期
- 使用keep-alive会增加两个生命周期函数,分别是:
onActivated
/onDeactivated
onActivated
在组件挂载时会被调用,onDeactivated
在组件卸载时会被调用。- 这两个钩子不仅适用于
<KeepAlive>
缓存的根组件,也适用于缓存树中的后代组件。
<template>
<KeepAlive>
<component :is="units[i].comName" />
</KeepAlive>
</template>
<script setup>
import { ref,onActivated,onDeactivated, onMounted, onUnmounted } from 'vue'
onMounted(() => {
console.log("初始化")
})
onActivated(() => {
console.log("keepAlive 初始化")
})
onDeactivated(() => {
console.log("keepAlive 销毁")
})
onUnmounted(() => {
console.log("销毁")
})
</script>
<style scoped></style>
转载自:https://juejin.cn/post/7246638858912448569