Appearance
vue之api-onActivated(激活)和onDeactivated(停用 )
介绍
回调函数,两者都用于<keep-alive>
包裹的组件,组件缓存(组件插入DOM)触发onActivated,停用(组件从 DOM移除)触发onDeactivated。
onActivated和onDeactivated在服务器端渲染期间都不会被调用
这两个生命周期都应用于我们的组件缓存结合<keep-alive>
使用,是缓存实例的生命周期
简单来说就是:
一个持续存在的组件通过 onActivated() 和 onDeactivated() 注册相应的两个状态的生命周期钩子:
语法
JS
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
// 调用时机为首次挂载
// 以及每次从缓存中被重新插入时
})
onDeactivated(() => {
// 在从 DOM 上移除、进入缓存
// 以及组件卸载时调用
})
</script>
使用
接下来我们写一个demo,看看onActivated和onDeactivated的使用,先来看看如何使用
JS
<template>
<div>
<p>当前时间: {{ currentTime }}</p>
</div>
</template>
<script setup>
import { ref, onActivated, onDeactivated } from 'vue';
const currentTime = ref(new Date().toLocaleTimeString());
// 激活时执行
onActivated(() => {
console.log('组件被激活了!');
updateTime();
});
// 停用时执行
onDeactivated(() => {
console.log('组件被停用了!');
clearInterval(timeInterval);
});
let timeInterval;
// 更新当前时间
function updateTime() {
timeInterval = setInterval(() => {
currentTime.value = new Date().toLocaleTimeString();
}, 1000);
}
</script>
👉 <keep-alive>
包裹
这个时候我们查看控制台,却没有看到组件被激活和停用的日志输出,因为我们还没有使用<keep-alive>
来缓存组件,而onActivated(激活)和onDeactivated(停用 )这两个生命周期钩子只有在组件被缓存的情况下才会被触发。
我们引入这个组件,使用<keep-alive>
包裹,这个时候就可以看到我们的输出了
JS
<template>
<keep-alive>
<Demo v-if="isActive" />
</keep-alive>
<button @click="isActive = !isActive">切换组件</button>
</template>
<script setup>
import { ref } from 'vue';
import Demo from '@/pages/demo.vue';
const isActive = ref(true);
</script>
来回切换组件的时候,控制台输出日志:
JS
组件被停用了!
组件被激活了!
源码实现
在源码的实现上,vue3之中是经过lifeCycle 钩子管理的,我们简单看看核心源码
👉 registerLifecycleHook函数
JS
// 生命钩子注册函数
function registerLifecycleHook(type, hook) {
// 在组件的生命周期管理中,将钩子注册到相应的钩子类型(activated 或 deactivated)
const instance = getCurrentInstance();
if (instance) {
if (!instance[type]) {
instance[type] = [];
}
instance[type].push(hook);
}
}
我们可以查看instance对象信息
js
getCurrentInstance() 返回的是当前组件的实例(instance)
instance包含了所有的组件信息,比如 props、data、methods
//代码信息
const instance = getCurrentInstance();
console.log(instance); // 输出当前组件的实例对象
👉注册钩子
JS
// Vue 核心实现的一部分伪代码
export function onActivated(hook) {
// 注册生命周期钩子,只有组件被缓存并且重新激活时才会触发
registerLifecycleHook('activated', hook);
}
export function onDeactivated(hook) {
// 注册生命周期钩子,只有组件被停用并缓存时才会触发
registerLifecycleHook('deactivated', hook);
}
👉 激活和停用组件
JS
// 组件激活时
function activateComponent(instance) {
// 如果组件被激活并且它有注册的 onActivated 钩子,则执行
if (instance.activated) {
instance.activated.forEach(hook => hook());
}
}
// 组件停用时
function deactivateComponent(instance) {
// 如果组件被停用并且它有注册的 onDeactivated 钩子,则执行
if (instance.deactivated) {
instance.deactivated.forEach(hook => hook());
}
}
onActivated和onDeactivated利用registerLifecycleHook将activated和deactivated钩子函数注册到instance对象上,然后通过deactivated和activated状态来触发这些钩子函数。
👉项目使用 项目之中使用的时候,我们一般在路由之中包裹使用
JS
<template>
<keep-alive>
<router-view></router-view>
</keep-alive>
</template>