Skip to content

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>

Released under the MIT License.