创建基本组件结构
父组件
//father.vue
<template>
<div class="father">
父组件
<span>父组件数值:{{val}}</span>
<button @click="add">父组件+1</button>
<button @click="switchChild">切换子组件</button>
<KeepAlive>
<template v-if="isShowChild">
<!--子组件-->
<son-node/>
</template>
<template v-else>
<div>hahah</div>
</template>
</KeepAlive>
</div>
</template>
<script setup lang="ts">
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted, ref} from 'vue'
import TestComSon from './TestComSon.vue';
onBeforeMount(()=>console.log('%c父组件挂载前onBeforeMount','color:green'))
onMounted(()=>console.log('%c父组件挂载后onMounted','color:green'))
onBeforeUpdate(()=>console.log('%c父组件升级前onBeforeUpdate','color:green'))
onUpdated(()=>console.log('%c父组件升级后onUpdated','color:green'))
onBeforeUnmount(()=>console.log('%c父组件卸载前onBeforeUnmount','color:green'))
onUnmounted(()=>console.log('%c父组件卸载后oonUnmounted','color:green'))
const val = ref(1)
const isShowChild = ref(true)
const add = ()=>{
val.value+=1;
}
const switchChild = ()=>{
isShowChild.value = !isShowChild.value
}
</script>
<style scoped>
.father{
width: 300px;
height: 300px;
border: 1px solid green;
}
</style>
父组件中的生命周期触发时都做了对应的打印,用keep-alive包裹了子组件。
子组件:
<template>
<div class="son">
子组件
</div>
</template>
<script setup lang="ts">
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onActivated,
onDeactivated
} from 'vue'
onBeforeMount(()=>console.log('%c子组件挂载前onBeforeMount','color:gold'))
onMounted(()=>console.log('%c子组件挂载后onMounted','color:gold'))
onBeforeUpdate(()=>console.log('%c子组件升级前onBeforeUpdate','color:gold'))
onUpdated(()=>console.log('%c子组件升级后onUpdated','color:gold'))
onBeforeUnmount(()=>console.log('%c子组件卸载前onBeforeUnmount','color:gold'))
onUnmounted(()=>console.log('%c子组件卸载后onUnmounted','color:gold'))
onActivated(()=>console.log('%c子组件激活后onActivated','color:gold'))
onDeactivated(()=>console.log('%c子组件注销后onDeactivated','color:gold'))
</script>
<style scoped>
.son{
width: 200px;
height: 200px;
border: 2px solid gold;
}
</style>
在子组件中对响应的生命周期也做了打。因为被keep-alive包裹,所以添加了onActivated
和onDeactivated
两个生命周期。
初始加载
当初始加载界面的时候,我们可以看到生命周期的触发情况如下:
父组件先执行了onBeforeMount
,然后子组件编译->挂载->激活,最后是父组件挂载。
父组件中数值发生变化
当点击了父组件中的+1按钮时,打印如下:
触发了父组件中的update
生命周期
父组件中切换子组件
当父组件中通过按钮切换不同的子组件时,打印如下:
子组件注销:
子组件激活:
在触发了子组件onDeactivated
,onActivated
事件前后,分别触发了父组件的onBeforeUpdate
和onUpdated
生命周期。
组件卸载
在组件卸载时,打印如下:
可以看到,子组件先于父组件卸载。
总结:
1.挂载时,父组件先编译->子组件编译->子组件挂载->子组件激活(被keep-live包裹时)->父组件挂载
2.父组件中显隐被keep-live包裹的子组件,则触发子组件的onActivated,onDeactivated生命周期
3.卸载时,父组件先触发onBeforeUnmount->子组件顺利卸载->父组件卸载