【Vue3 生命周期与组合式API】

一、Vue3 生命周期概述

Vue3 的生命周期钩子函数可以帮助开发者在组件的不同阶段执行特定的逻辑,以便更好地管理和优化应用。

Vue的组件实例从创建到销毁会经历一系列的生命周期阶段,每个阶段都有相应的钩子函数,开发者可以利用这些钩子函数在组件的生命周期中的关键时刻注入自己的代码。

  1. 初始化阶段:在这个阶段,Vue会进行事件和生命周期的初始化。对于组合式 API,这个阶段主要与setup函数的调用相关。

  2. 模板编译阶段:将模板编译成渲染函数的阶段。这个阶段在使用组合式 API 时通常不需要直接操作。

  3. 挂载阶段:组件被挂载到 DOM 上。在组合式 API 中,对应的生命周期钩子函数是onBeforeMountonMounted

  4. 更新阶段:当组件的数据变化时,组件会重新渲染。在这个阶段,可以利用onBeforeUpdateonUpdated钩子函数执行特定逻辑。

  5. 卸载阶段:组件从 DOM 中移除。这个阶段的钩子函数是onBeforeUnmountonUnmounted

在 Vue3 的组合式 API 中,所有这些生命周期钩子函数都可以直接在setup函数中使用,这提供了一种更灵活、更函数式的方式来组织和复用组件逻辑。通过这种方式,Vue3 不仅保持了其响应式系统的核心优势,还在组件逻辑复用方面做出了革新。

二、Vue3 组合式API 与选项式API 的对比

Vue.js 提供了两种主要的API风格来编写组件:选项式 API 和组合式 API。

1. 选项式API 生命周期钩子函数

选项式 API 是 Vue2.x 引入的,Vue3 亦保留了这种风格。在选项式 API 中,组件的逻辑是通过一个包含各种属性的对象来组织的,其中包括数据、方法、生命周期钩子等。

常用的生命周期钩子函数包括:

  • beforeCreate:在实例初始化之后,数据观察和事件/侦听器配置之前被调用。
  • created:在实例创建完成后被立即调用,此时数据观察、属性和方法的运算、事件/侦听器的回调已经设置好了。
  • beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。
  • mounted:在实例被挂载后调用,此时可以访问到 DOM。
  • beforeUpdate:在数据变化导致的虚拟DOM重新渲染和打补丁之前调用。
  • updated:在数据更改导致的虚拟DOM重新渲染和打补丁之后调用。
  • beforeUnmount(Vue3 新增):在卸载组件实例之前调用。
  • unmounted(Vue3 新增):在卸载组件实例之后调用。

这些生命周期钩子提供了在组件不同阶段执行代码的机会,让开发者可以有效地管理组件的状态和行为。

2. 组合式API 的优势

Vue3 引入了组合式 API 作为一个全新的编写组件的方式,旨在解决 Vue2.x 在组件复用和逻辑组织方面的一些限制。

组合式API 的主要优势包括:

  • 更好的逻辑组织和复用:组合式 API 通过 setup 函数和其他 Composition API 函数(如 reactive, computed, watch)允许开发者更自然地提取和重用逻辑代码,而不是将逻辑分散在选项式 API 的不同选项中。
  • 更清晰的代码结构:组合式 API 使得相关功能的代码更加集中,有助于提高代码的可读性和维护性。
  • 对 TypeScript 的更好支持:组合式 API 与 TypeScript 配合得更紧密,提供了更好的类型推导和类型检查,使得开发大型应用时代码更健壮。
  • 更细粒度的代码分割:通过使用组合式 API,开发者可以更灵活地控制组件的各个方面,比如状态的声明、副作用的执行等,从而更精细地优化组件的行为和性能。

在生命周期管理上的优势

组合式 API 中,生命周期钩子也被作为函数(如 onMounted, onUpdated)提供,可以直接在 setup 函数内部使用。这种方式使得生命周期钩子的调用更加直观和灵活,可以更紧密地与组件的其他逻辑结合,提高了代码的组织性和可读性。此外,它也让跨组件的逻辑复用变得更加简单,可以将生命周期钩子和相关逻辑一起封装和复用。

三、Vue3 组合式API 生命周期钩子函数

1. setup 函数

setup 函数是 Vue3 组合式 API 中最重要的一个新概念。它在组件创建之初就被调用,用于替代 Vue2 中的 data, computed, methods, watch, 以及生命周期钩子函数的部分功能。

特点和作用:

  • setup 函数执行时,组件的 props 和 context(包括 slots 和 emits)已经被初始化。
  • 该函数返回的对象中的属性和方法将被暴露给组件的模板。
  • setup 函数是响应式的,可以使用 reactive, ref 等 API 在其中创建和管理状态。

2. onBeforeMount

在组件被挂载到 DOM 之前调用。

代码示例:

import { onBeforeMount } from 'vue';

export default {
  setup() {
    onBeforeMount(() => {
      console.log('Component is about to be mounted!');
    });
  }
}

使用场景:

  • 初始化或配置 DOM 相关的操作前的准备工作。

3. onMounted

在组件被挂载到 DOM 之后调用。

代码示例:

import { onMounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('Component has been mounted!');
    });
  }
}

使用场景:

  • 访问或修改 DOM 元素。
  • 发送 AJAX 请求获取数据。

4. onBeforeUpdate

在组件更新之前调用。

代码示例:

import { onBeforeUpdate } from 'vue';

export default {
  setup() {
    onBeforeUpdate(() => {
      console.log('Component is about to update!');
    });
  }
}

使用场景:

  • 在组件更新前执行特定操作,如读取当前 DOM 状态。

5. onUpdated

在组件更新之后调用。

代码示例:

import { onUpdated } from 'vue';

export default {
  setup() {
    onUpdated(() => {
      console.log('Component has been updated!');
    });
  }
}

使用场景:

  • 更新完成后的 DOM 操作。
  • 更新完成后的清理工作。

6. onBeforeUnmount

在组件卸载之前调用。

代码示例:

import { onBeforeUnmount } from 'vue';

export default {
  setup() {
    onBeforeUnmount(() => {
      console.log('Component is about to be unmounted!');
    });
  }
}

使用场景:

  • 清理组件使用的资源,如事件监听器。

7. onUnmounted

在组件卸载之后调用。

代码示例:

import { onUnmounted } from 'vue';

export default {
  setup() {
    onUnmounted(() => {
      console.log('Component has been unmounted!');
    });
  }
}

使用场景:

  • 完成组件卸载后的最后清理工作。

8. 其他生命周期钩子函数

Vue3 还提供了其他一些生命周期钩子函数,用于特定场景:

  • onActivatedonDeactivated:用于 <keep-alive> 缓存的组件激活和停用。
  • onErrorCaptured:用于捕获组件树中所有子孙组件的错误。
  • onRenderTrackedonRenderTriggered:用于调试,追踪和触发渲染。

四、生命周期钩子函数的应用实例

示例1:数据加载和DOM操作

onMounted 钩子函数是获取数据的理想选择,它保证了组件已经被挂载,因此可以安全地访问到 DOM 元素或进行数据请求。

import { onMounted, ref } from 'vue';
import axios from 'axios';

export default {
  setup() {
    const posts = ref([]);

    onMounted(async () => {
      try {
        const response = await axios.get('https://api.example.com/posts');
        posts.value = response.data;
      } catch (error) {
        console.error('Failed to fetch posts:', error);
      }
    });

    return { posts };
  }
}

使用 onMounted 钩子函数发送 AJAX 请求获取数据,并将数据存储在响应式的 posts 变量中。

示例2:资源清理

在组件中注册事件监听器或定时器时,很重要的一点是在组件卸载前清理这些资源,以避免内存泄漏。这可以通过 onUnmounted 钩子函数来实现。

import { onMounted, onUnmounted, ref } from 'vue';

export default {
  setup() {
    const isConnected = ref(false);

    const connect = () => {
      // 假设这是连接到某个服务的函数
      isConnected.value = true;
    };

    const disconnect = () => {
      // 断开连接
      isConnected.value = false;
    };

    onMounted(() => {
      connect();
      // 假设我们监听 window 的 resize 事件
      window.addEventListener('resize', connect);
    });

    onUnmounted(() => {
      disconnect();
      window.removeEventListener('resize', connect);
    });

    return { isConnected };
  }
}

在这个示例中,onMounted 用于注册事件监听器和初始化连接,而 onUnmounted 用于在组件销毁时移除事件监听器和清理资源。

示例3:依赖于props的异步操作

有时需要在组件中根据 props 的变化来执行异步操作,例如根据从父组件传入的用户ID获取用户信息。这种场景下可以使用 watchonMounted 钩子函数结合使用。

import { watch, onMounted, ref } from 'vue';
import axios from 'axios';

export default {
  props: {
    userId: Number
  },
  setup(props) {
    const userInfo = ref(null);

    const fetchUserInfo = async (id) => {
      try {
        const response = await axios.get(`https://api.example.com/users/${id}`);
        userInfo.value = response.data;
      } catch (error) {
        console.error('Failed to fetch user info:', error);
      }
    };

    onMounted(() => fetchUserInfo(props.userId));

    watch(() => props.userId, (newId) => {
      fetchUserInfo(newId);
    });

    return { userInfo };
  }
}

这个示例展示了如何在组件被挂载时以及 userId prop 更改时重新获取用户信息。这种方式确保了即使 userId 在组件生命周期内发生变化,用户信息也能保持最新。

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武帝为此

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值